Compare commits

...

3374 Commits

Author SHA1 Message Date
FreeScout
b564d20627 Merge branch 'master' of github.com:freescout-helpdesk/freescout into dist 2024-11-29 20:45:28 -08:00
FreeScout
3562298031 v1.8.159 2024-11-29 20:45:00 -08:00
FreeScout
7706d52e63 Fix text bolding issue - closes #4367 2024-11-29 06:31:14 -08:00
FreeScout
ff2e92f1ff Add layout.title.name hook 2024-11-29 06:18:39 -08:00
FreeScout
4b2f385e43 Fix Spanish translation #4376 from anxodio/patch-2
Fix Spanish translation
2024-11-28 17:17:59 +01:00
Àngel Fernández
a15c29bea0 Fix bad translation
The translation says the opposite than the original intention
2024-11-28 16:10:32 +01:00
FreeScout
a0594bf6d9 Fix Undefined array key 2 error on fetching - closes #4372 2024-11-28 04:43:24 -08:00
FreeScout
6e0a213003 Fix text bolding issue - closes #4367 2024-11-28 04:30:42 -08:00
FreeScout
8024c72db5 Optimize UpdateFolderCounters Job #4374 from mahavirn/optimize-update-folder-count-job
Optimize UpdateFolderCounters Job
2024-11-28 11:50:10 +03:00
Mahavir Nahata
ecc9ea9ab9 Optimize UpdateFolderCounters Job 2024-11-28 13:38:06 +05:30
FreeScout
b3dbad9a6e Show more detailed errors on fetching - closes #4372 2024-11-27 04:09:16 -08:00
FreeScout
ccdbd265c8 Show more detailed errors on fetching - closes #4372 2024-11-27 01:09:34 -08:00
FreeScout
a0659a8971 Add Precedence:list to the list of no auto-reply send headers - closes #4363 2024-11-24 23:01:19 -08:00
FreeScout
ef4d37f308 Fix text bolding issue - closes #4367 2024-11-24 22:08:36 -08:00
FreeScout
a49fd0ad33 Clear cache manually in update.sh to avoid post-update issues - closes #4366 2024-11-24 02:06:17 -08:00
FreeScout
190d2daece Fix Argument 1 (lastErrors) must be of type array in Carbon 2024-11-23 20:58:26 -08:00
FreeScout
bfbfeb2e66 Add vendor files to dist 2024-11-22 00:37:13 -08:00
FreeScout
a11df91aa4 Merge branch 'master' of github.com:freescout-helpdesk/freescout into dist 2024-11-22 00:34:55 -08:00
FreeScout
4d51348487 v1.8.158 2024-11-22 00:34:40 -08:00
FreeScout
0e7e1a54f4 Fix an issue with the SPAN tag being added in the editor - closes #4354 2024-11-17 09:35:13 -08:00
FreeScout
b7938df35b Do not check In-Reply-To header when processing @fwd instruction - closes #4348 2024-11-15 02:24:52 -08:00
FreeScout
b622bbb284 Remove Webklex/laravel-imap library 2024-11-15 02:14:50 -08:00
FreeScout
009c51e245 Merge branch 'master' of github.com:freescout-helpdesk/freescout into dist 2024-11-14 23:36:24 -08:00
FreeScout
21fe296303 v1.8.157 2024-11-14 23:36:13 -08:00
FreeScout
2a0200f46d Fix table wizard in the editor - closes #4345 2024-11-14 00:15:41 -08:00
FreeScout
f5971fb24f Adjust placeholder in translations - closes #4346 2024-11-13 23:39:12 -08:00
FreeScout
76c550ff99 Croatian translation #4346 from shunkica/hr-translation
Croatian translation
2024-11-14 08:23:39 +01:00
shunkica
2d1fec3cb8 Update hr.json 2024-11-13 23:11:37 +01:00
shunkica
097f10ec18 Update croatian translations 2024-11-13 23:06:59 +01:00
FreeScout
b63bad55ac Allow to set APP_FETCHING_BUNCH_SIZE env parameter - closes #4343 2024-11-13 05:26:10 -08:00
FreeScout
94c1c01480 Do not reset Default Redirect settings for users when saving Mailbox Permissions - closes #4339 2024-11-12 05:02:27 -08:00
FreeScout
21053200f0 Add conversations.table_sorting hook - closes #4338 2024-11-12 02:01:40 -08:00
FreeScout
8d65bdf0bf Fix @fwd forwarding when styles are present in the email body - closes #4333 2024-11-11 04:23:28 -08:00
FreeScout
e2e3682ca8 Update readme 2024-11-11 00:55:31 -08:00
FreeScout
fc7f4bfc35 Fix moving emails to a folder on fetching on mail servers not supporting MOVE command - closes #4313 2024-11-07 21:14:55 -08:00
FreeScout
e2360f2146 Merge branch 'master' of github.com:freescout-helpdesk/freescout into dist 2024-11-04 08:24:58 -08:00
FreeScout
910edcaea2 v1.8.156 2024-11-04 08:24:43 -08:00
FreeScout
ffcce029f5 Fix Undefined variable customer in thread.blade.php - closes #4321 2024-11-04 08:22:41 -08:00
FreeScout
b6987ddb90 Merge branch 'master' of github.com:freescout-helpdesk/freescout into dist 2024-11-01 21:45:43 -07:00
FreeScout
cbeffb850d v1.8.155 2024-11-01 21:45:35 -07:00
FreeScout
bbcba6e266 Allow to hide from support agents customers from non-visible mailboxes - closes #4316 2024-11-01 10:13:41 -07:00
FreeScout
9a6429ea97 Allow to hide from support agents customers from non-visible mailboxes - closes #4316 2024-11-01 00:35:14 -07:00
FreeScout
52e5ecf905 Update German translation 2024-10-29 03:03:18 -07:00
FreeScout
2912422a31 Fix typo in user profile.blade.php 2024-10-27 10:55:21 -07:00
FreeScout
e17da2b6c0 Update Japanese translation 2024-10-26 07:16:11 -07:00
FreeScout
b276cea24a Fix error in Thread->getFromHeader() 2024-10-26 02:55:53 -07:00
FreeScout
e7ec7e7364 Set CURLOPT_FOLLOWLOCATION in Helper::getRemoteFileContents() 2024-10-26 02:52:51 -07:00
FreeScout
46add74e4f Show From address in the conversation when From and Reply-To headers are different in the email - closes #4287 2024-10-18 01:38:33 -07:00
FreeScout
4e8cd07303 Fix decoding Japanese symbols in the email body in gb2312 encoding - closes #4282 2024-10-16 22:50:08 -07:00
FreeScout
5db8906a86 Add hooks: conversation.convinfo.prepend and conversation.convinfo.before_nav - closes #4279 2024-10-08 22:46:52 -07:00
FreeScout
927afe44c7 Add Delivered-To:Autoresponder to the list of autoresponder headers 2024-10-04 11:07:41 -07:00
FreeScout
30b07a82c7 Merge branch 'master' of github.com:freescout-helpdesk/freescout into dist 2024-10-04 04:34:21 -07:00
FreeScout
c80ce3d4f8 v1.8.154 2024-10-04 04:34:11 -07:00
FreeScout
980035fecc Improve the email search by Message-Id in Show Original window - closes #4266 2024-10-04 04:31:47 -07:00
FreeScout
6af389655c Check if user is deleted on Permissions and Notifications pages 2024-10-03 00:52:20 -07:00
FreeScout
eb5c8fac12 Create User::deleteUser() method 2024-10-03 00:26:33 -07:00
FreeScout
3f90a9bad3 Improve connection sleep time selection when fetching emails to avoid connection setup failed error - closes #4227 2024-10-02 03:53:10 -07:00
FreeScout
0280e4f30d Fix SMTP authentication not working in some cases due to setAuthMode() used in Swiftmailer - closes #4250 2024-10-02 03:34:58 -07:00
FreeScout
b92e502fb0 Fix null given error in getMessageNumber() - closes #4257 2024-09-27 07:00:31 -07:00
FreeScout
8cb8a180b7 Fix null given error in getMessageNumber() - closes #4257 2024-09-27 06:58:39 -07:00
FreeScout
5c9ab337ea Add vendor files to dist 2024-09-22 07:01:39 -07:00
FreeScout
f6e18818cd Merge branch 'master' of github.com:freescout-helpdesk/freescout into dist 2024-09-22 07:00:04 -07:00
FreeScout
880205fc59 v1.8.153 2024-09-22 06:33:42 -07:00
FreeScout
c073511378 Update German translation 2024-09-22 06:17:35 -07:00
FreeScout
275454d479 Add CSRF check to the Delete all files link in Manage App Logs 2024-09-20 05:57:16 -07:00
FreeScout
a96b31fb99 Avoid process list trancation when checking running commands - closes #4237 2024-09-20 02:58:03 -07:00
FreeScout
a19bfd421c Improve connection sleep time selection when fetching emails to avoid connection setup failed error - closes #4227 2024-09-12 23:53:52 -07:00
FreeScout
fbae84ba3c Improve connection sleep time selection when fetching emails to avoid connection setup failed error - closes #4227 2024-09-12 22:30:16 -07:00
FreeScout
e63904a53b Add X-Autoresponder to the list of auto-responder headers - closes #4226 2024-09-12 00:19:38 -07:00
FreeScout
5a989ec257 Improve @fwd detection when forwarding emails - closes #2940 2024-09-11 10:12:58 -07:00
FreeScout
b90f3d7204 Change /bin/sh to /bin/bash in update.sh - closes #4208 2024-09-03 00:54:17 -07:00
FreeScout
03c234edec Fix an issue with emails being empty when fetching from iCloud - closes #4202 2024-08-29 00:42:12 -07:00
FreeScout
af2b1254e8 Update Polish translation 2024-08-28 23:52:21 -07:00
FreeScout
f218fe17d0 Add vendor files to dist 2024-08-27 23:15:39 -07:00
FreeScout
a2979a4406 Merge branch 'master' of github.com:freescout-helpdesk/freescout into dist 2024-08-27 23:15:16 -07:00
FreeScout
e4dd3b4ad1 v1.8.152 2024-08-27 23:15:04 -07:00
FreeScout
aa713a3a57 Fix an issue with plain text emails having empty body - closes #4181 2024-08-27 23:13:45 -07:00
FreeScout
adc9921108 Add vendor files to dist 2024-08-27 04:52:34 -07:00
FreeScout
f326b14776 Merge branch 'master' of github.com:freescout-helpdesk/freescout into dist 2024-08-27 04:52:00 -07:00
FreeScout
afaf1f53ab v1.8.151 2024-08-27 04:50:57 -07:00
FreeScout
23bb50eb86 Fix out of memory on Status page when there are many background jobs - closes #4197 2024-08-27 03:58:19 -07:00
FreeScout
39824c876d Fix Undefined array key 1 error on fetching emails - closes #4195 2024-08-26 22:22:06 -07:00
FreeScout
ca1a7d0900 Fix non-multipart emails contain headers in the bodies - closes #4181 2024-08-24 03:02:23 -07:00
FreeScout
351eff9b80 Fix checking POP3 connection when PHP Request Shutdown: Unexpected characters at end of address error occurs 2024-08-23 22:48:46 -07:00
FreeScout
e037011c55 Added Kazakh language 2024-08-16 09:10:07 -07:00
FreeScout
c0ce07a2b9 Merge branch 'master' of github.com:freescout-helpdesk/freescout into dist 2024-08-15 20:10:13 -07:00
FreeScout
94f11a9155 v1.8.150 2024-08-15 20:09:47 -07:00
FreeScout
dff234ffbe Allow to disable quotes around SINCE date in IMAP search query via APP_SINCE_WITHOUT_QUOTES_ON_FETCHING env parameter - closes #4175 2024-08-15 20:07:55 -07:00
FreeScout
223b4d12dc Merge branch 'master' of github.com:freescout-helpdesk/freescout into dist 2024-08-14 09:51:38 -07:00
FreeScout
b33fb5e1d3 v1.8.149 2024-08-14 09:51:26 -07:00
FreeScout
3511e7acb2 Fix configuring MS365 SMTP via oAuth - closes #4179 2024-08-13 22:23:07 -07:00
FreeScout
be4a1234c3 Improve Webklex/php-imap memory usage 2024-08-13 11:24:45 -07:00
FreeScout
823014d4e9 Call parseRawBody() in Webklex Message if body has not been parsed yet 2024-08-13 11:08:16 -07:00
FreeScout
310d3290fe Do not add quotes around the date in IMAP SINCE query - closes #4175 2024-08-11 03:44:03 -07:00
FreeScout
07765cf8ff Populate variables in custom Mailbox names inside emails sent to customers - closes #4169 2024-08-08 05:00:40 -07:00
FreeScout
c4a6585cc7 Add vendor files to dist 2024-08-08 04:17:10 -07:00
FreeScout
d99d991650 Merge branch 'master' of github.com:freescout-helpdesk/freescout into dist 2024-08-08 04:16:35 -07:00
FreeScout
6e8682e693 v1.8.148 2024-08-08 04:15:59 -07:00
FreeScout
87eab76574 Set MS365 SMTP credentials automatically only when outlook.office365.com SMTP host is set - closes #4151 2024-08-08 04:00:35 -07:00
FreeScout
a011948149 Make toSql() comparison compatible with PostgreSQL - closes #4167 2024-08-07 03:56:31 -07:00
FreeScout
b9391d87dc Leave other emails unread when an exception happens during fetching of one of them - closes #4159 2024-08-02 23:32:49 -07:00
FreeScout
7e7f0a0d10 Leave other emails unread when an exception happens during fetching of one of them - closes #4159 2024-08-01 23:34:38 -07:00
FreeScout
8e62d70986 Correctly processs invalid dates when fetching emails - closes #4159 2024-08-01 21:22:33 -07:00
FreeScout
02e5fa8535 Correctly process invalid mail Reply-To headers - closes #4158 2024-08-01 21:01:42 -07:00
FreeScout
2dc8d061e1 Prefill SMTP username and password for MS365 if those fields are empty - closes #4151 2024-07-30 22:21:34 -07:00
FreeScout
efca2acbe2 Log Helper::getRemoteFileContents() errors 2024-07-22 09:50:01 -07:00
FreeScout
029e5c8a1f Execute hooks when performing conversations bulk delete to Deleted folder - closes #4141 2024-07-22 06:30:26 -07:00
FreeScout
7383b95864 Merge branch 'master' of github.com:freescout-helpdesk/freescout into dist 2024-07-21 06:19:34 -07:00
FreeScout
5be99f03f3 v1.8.147 2024-07-21 06:19:27 -07:00
FreeScout
da522d8d58 Fix Disconnect link for MS365 in Fetching settings - closes #4136 2024-07-18 02:30:49 -07:00
FreeScout
60ac03df04 Improve App Key check in tools.php 2024-07-17 09:38:38 -07:00
FreeScout
5a22011fe6 Improve sanitizing Path to PHP in tools.php 2024-07-17 09:37:21 -07:00
FreeScout
09f4908def Fix Call to a member function getFirstName() on null in notification.blade.php - closes #4132 2024-07-16 22:17:20 -07:00
FreeScout
8172db9cdb Improve sanitizing Path to PHP in tools.php 2024-07-16 22:12:57 -07:00
FreeScout
05e7e1e739 Improve sanitizing Path to PHP in tools.php 2024-07-16 07:03:27 -07:00
FreeScout
b2c72775dd Merge pull request #4130 from IchHabeHunger54/master
Add conversation->changeSubject() and conversation.subject_changed action
2024-07-16 13:55:52 +03:00
Neustifter, David
9eb7457097 Add Conversation->changeSubject() and conversation.subject_changed action 2024-07-16 12:47:07 +02:00
FreeScout
0b7d1dc06f Allow padding-left and simiar CSS properties when purifying HTML 2024-07-11 00:53:42 -07:00
FreeScout
2f9d1bf92e Merge branch 'master' of github.com:freescout-helpdesk/freescout into dist 2024-07-08 01:44:11 -07:00
FreeScout
de405fe60f v1.8.146 2024-07-08 01:44:01 -07:00
FreeScout
9bb3ee9bc1 Use only forward slashes in attachment URLs - closes #4106 2024-07-04 21:04:52 -07:00
FreeScout
5ab6a42808 Fallback to getPathname() for uploaded files - closes #4105 2024-07-04 21:03:14 -07:00
FreeScout
9b5286efca Fallback to getPathname() for uploaded files - closes #41054105 2024-07-04 20:59:32 -07:00
FreeScout
78e1067c07 Do not duplicate recipient in conversation CC field - closes #4112 2024-07-03 08:24:55 -07:00
FreeScout
c19c4ee217 Fix conversation draft not visible in Drafts after undoing new conversation - closes #4112 2024-07-03 07:55:25 -07:00
FreeScout
5ef26eaf32 Fix error message when can not fetch specific email vai MailHelper::fetchMessage() - closes #4097 2024-07-03 04:37:07 -07:00
FreeScout
16843c9d6a Fix Datatables sort_desc.png not found - closes #4107 2024-07-03 00:45:22 -07:00
FreeScout
a21f5c9d53 Merge branch 'master' of github.com:freescout-helpdesk/freescout 2024-07-02 12:02:26 -07:00
FreeScout
97cea6cdef Fix Undefined array key auth_mode on sending emails - closes #4103 2024-07-02 12:02:09 -07:00
FreeScout
12c6552259 Merge pull request #4099 from gabllux/master
Handle null values on outOauthEnabled() - closes #4094
2024-07-02 20:54:56 +02:00
gabllux
04aaeb4cc1 Handle null values on outOauthEnabled() - closes https://github.com/freescout-help-desk/freescout/issues/4094 2024-06-25 21:33:01 +02:00
FreeScout
7c3e57aa57 Merge branch 'master' of github.com:freescout-helpdesk/freescout into dist 2024-06-19 11:39:48 -07:00
FreeScout
f90ba3d6d6 v1.8.145 2024-06-19 11:39:29 -07:00
FreeScout
4fe2a9333e Improve SMTP oAuth implementation - closes #4084 2024-06-19 09:47:03 -07:00
FreeScout
bd59fa5ef5 Mention posix_isatty() function in \Helper::checkRequiredFunctions() 2024-06-19 04:24:00 -07:00
FreeScout
989c729834 Add created_at index to threads table - closes #4069 2024-06-18 02:26:10 -07:00
FreeScout
a57a424067 Update readme 2024-06-18 00:46:15 -07:00
FreeScout
755e4f0cd7 Add vendor files to dist 2024-06-17 22:12:38 -07:00
FreeScout
a2a0539316 Merge branch 'master' of github.com:freescout-helpdesk/freescout into dist 2024-06-17 22:11:43 -07:00
FreeScout
e8975d04d6 v1.8.144 2024-06-17 22:11:34 -07:00
FreeScout
d6eac44275 Show more detailed errors when IMAP authentication fails 2024-06-17 10:54:23 -07:00
FreeScout
ea39e24727 Rename STARTTLS Encryption method in Fetching settings 2024-06-17 06:31:18 -07:00
FreeScout
5a290b3ad3 Allow to enable debug in Status - Tools - Fetching section 2024-06-16 02:21:06 -07:00
FreeScout
ce523c51e7 Show debug log when testing fetching 2024-06-16 02:05:42 -07:00
FreeScout
5bcde678d1 Update repo URL in self-updater 2024-06-15 08:30:44 -07:00
FreeScout
98e74e53f2 Update repo link 2024-06-14 00:36:27 -07:00
FreeScout
bde2da820c Update repo URL in self-updater 2024-06-14 00:06:10 -07:00
FreeScout
4b2dd40d99 Update also inactive modules via freescout:module-update command 2024-06-13 03:22:17 -07:00
FreeScout
4d7f8d1f50 Microsoft Exchange oAuth for SMTP - closes #4072 2024-06-12 22:21:03 -07:00
FreeScout
8510ee8224 Microsoft Exchange oAuth for SMTP - closes #4072 2024-06-12 20:45:58 -07:00
FreeScout
7e8e514e7b Microsoft Exchange oAuth for SMTP - closes #4072 2024-06-12 11:45:08 -07:00
FreeScout
fb3b0d3a49 Update readme 2024-06-11 22:18:50 -07:00
FreeScout
aaacc6d3fa Fix Call to undefined function get_current_user() error on Status page - closes #4067 2024-06-10 22:31:29 -07:00
FreeScout
3c199f697c Merge branch 'master' of github.com:freescout-helpdesk/freescout into dist 2024-06-10 10:25:57 -07:00
FreeScout
5c01c3793c v1.8.143 2024-06-10 10:25:45 -07:00
FreeScout
0ff901ef32 Fix Undefined variable $customer in thread.php - closes #4066 2024-06-10 10:24:36 -07:00
FreeScout
08a5d5f6ff Add MailHelper::parseEml() function 2024-06-10 04:42:42 -07:00
FreeScout
1fd00def95 Allow to call \Webklex\PHPIMAP\Message::make() without specifying uid 2024-06-10 01:27:24 -07:00
FreeScout
21a73fa5e6 Add vendor files to dist 2024-06-09 09:37:24 -07:00
FreeScout
c9b2c3cc36 Merge branch 'master' of github.com:freescout-helpdesk/freescout into dist 2024-06-09 09:36:57 -07:00
FreeScout
4ee876c134 v1.8.142 2024-06-09 09:36:48 -07:00
FreeScout
c1c713ef15 Show From for emails received from customers with multiple emails - closes #4059 2024-06-06 11:52:59 -07:00
FreeScout
b926cd5cf2 Do not show Mailbox is empty error when fetching via POP3 - closes #4060 2024-06-06 11:44:21 -07:00
FreeScout
325343c2cf Fix sending a new conversation to the customer with multiple emails - closes #4057 2024-06-05 04:00:26 -07:00
FreeScout
d9502ff348 Fix error in module:list command - closes #4056 2024-06-05 00:00:37 -07:00
FreeScout
585f8f49a7 Sort modules list in the Deactivate License dialog - closes #4055 2024-06-03 22:45:54 -07:00
FreeScout
505db999ad Fix mb_convert_encoding() invalid encoding error on fetching - closes #4051 2024-06-01 08:55:33 -07:00
FreeScout
d402dd5164 Catch mb_convert_encoding() error on fetching - closes #4051 2024-06-01 08:36:57 -07:00
FreeScout
a93cc2a08f Improve Gmail reply separation on fetching 2024-06-01 03:34:03 -07:00
FreeScout
0ac8685c63 Merge branch 'master' of github.com:freescout-helpdesk/freescout into dist 2024-05-30 04:55:43 -07:00
FreeScout
754b2fc40c v1.8.141 2024-05-30 04:55:26 -07:00
FreeScout
c32a68ed93 Remove All from current mailbox link from conversation page - closes #4041 2024-05-27 01:30:51 -07:00
FreeScout
c269311ef5 Skip auto-replies sent to the email notification on behalf of a user - #4035 2024-05-27 01:24:35 -07:00
FreeScout
04c28a9637 Disable Check Connection button on changing mailbox Fetching settings 2024-05-22 22:33:24 -07:00
FreeScout
6830a78e23 Show exclamation icon in mailbox connection settings tabs 2024-05-22 22:04:29 -07:00
FreeScout
3a4921344b Show exclamation icon in mailbox connection settings tabs 2024-05-22 22:02:03 -07:00
FreeScout
063b77f3df Fix IMAP folders not being retrieved in some cases 2024-05-22 21:50:26 -07:00
FreeScout
61e5f1fde5 Fix fetching emails forwarded using @fwd command - closes #4036 2024-05-21 11:36:15 -07:00
FreeScout
4f253bfab1 Fix reteiving the original message in Show Original window for moved conversations 2024-05-21 10:33:16 -07:00
FreeScout
c88ca44ff1 Find prev_thead iteratively looking in-reply-to and references #4026 from Som-Energia/master
Find prev_thead iteratively looking in-reply-to and references
2024-05-16 09:01:22 +03:00
FreeScout
2d871f2759 Merge branch 'master' of github.com:freescout-helpdesk/freescout into dist 2024-05-15 22:57:28 -07:00
FreeScout
2a0bac500c v1.8.140 2024-05-15 22:57:20 -07:00
FreeScout
cedf4de2ba Update TestWebklex command 2024-05-15 22:46:16 -07:00
Àngel Fernández
d9e1a7ae98 Find prev_thead iteratively looking in-reply-to and references 2024-05-15 18:15:31 +02:00
FreeScout
80118d579d Update general_help_request.md 2024-05-15 07:13:47 -07:00
FreeScout
0299c8be99 Switch to the new fetching library 2024-05-10 22:46:33 -07:00
FreeScout
70a7ec54ea Merge branch 'master' of github.com:freescout-helpdesk/freescout into dist 2024-05-10 22:15:09 -07:00
FreeScout
4876d37287 v1.8.139 2024-05-10 22:14:53 -07:00
FreeScout
9894ca78f0 app.csp_custom env parameter 2024-05-09 06:34:05 -07:00
FreeScout
99a4b4b4e1 Remove unwanted tags from HTML when editing threads - GHSA-985r-6qfc-hg8m 2024-05-06 00:52:36 -07:00
FreeScout
1169f5bae9 Strip unwanted tags from mailbox Auto Reply 2024-05-06 00:16:53 -07:00
FreeScout
a59619c153 Strip unwanted tags from mailbox signature when saving it 2024-05-06 00:14:00 -07:00
FreeScout
c4932c4c8e Fix CC and BCC fields when cloning a conversation - closes #4011 2024-05-05 09:44:35 -07:00
FreeScout
cb31699a6e Update Polish translation 2024-05-05 00:08:47 -07:00
FreeScout
41e6e10241 Update Polish translation 2024-05-05 00:07:28 -07:00
FreeScout
ce5c85f592 Remove FORM tags from HTML when editing threads - GHSA-985r-6qfc-hg8m 2024-05-04 23:15:05 -07:00
FreeScout
2614514bc6 Do not allow Prototype Pollution via getQueryParam() function - GHSA-rx6j-4c33-9h3r 2024-05-04 22:59:35 -07:00
FreeScout
a50c261f13 Merge branch 'master' of github.com:freescout-helpdesk/freescout into dist 2024-04-26 06:41:18 -07:00
FreeScout
b474193f97 v1.8.138 2024-04-26 06:41:10 -07:00
FreeScout
27a4f2e8ff Fix cron URL link - closes #4000 2024-04-26 03:53:37 -07:00
FreeScout
17024f814a Merge branch 'master' of github.com:freescout-helpdesk/freescout into dist 2024-04-22 09:35:48 -07:00
FreeScout
d18cc23149 v1.8.137 2024-04-22 09:35:36 -07:00
FreeScout
047111ffbb Fix Unknown hashing algorithm crc32c error in Webklex/php-imap library - closes #3991 2024-04-22 06:51:49 -07:00
FreeScout
8c5dbb4197 Fetch emails sent to multiple mailboxes on a per mailbox basis - closes #3941 2024-04-22 01:36:46 -07:00
FreeScout
7a6cbab8af Do not show closed conversations in non-standard folders - closes #3988 2024-04-20 23:17:20 -07:00
FreeScout
add6f179a4 Add folder.only_assigned_condition hook - closes #701 2024-04-20 22:27:13 -07:00
FreeScout
29d8c41395 Fix browser push notifications sent not to all users - closes #3880 2024-04-19 07:31:00 -07:00
FreeScout
0ecfa248ee Merge branch 'master' of github.com:freescout-helpdesk/freescout into dist 2024-04-18 23:35:34 -07:00
FreeScout
748c7c5de1 v1.8.136 2024-04-18 23:34:12 -07:00
FreeScout
2b5be510b7 Update Dutch translation 2024-04-16 06:34:24 -07:00
FreeScout
99ef4e6899 Do not run scheduled commands when running \Artisan::call() function - closes #3970 2024-04-15 07:17:25 -07:00
FreeScout
59b86a882e Fix attachments not being shown when re-opening a new conversation draft - closes #3957 2024-04-12 22:12:10 -07:00
FreeScout
a6a729189c Show system date and time on Status page instead of current user time 2024-04-12 22:03:48 -07:00
FreeScout
7829e9a3ba Merge branch 'master' of github.com:freescout-helpdesk/freescout into dist 2024-04-12 21:53:28 -07:00
FreeScout
a2e27f3ced v1.8.135 2024-04-12 21:53:13 -07:00
FreeScout
9175ce3646 Fix Parse error in Attachment.php - closes #3965 2024-04-12 21:52:35 -07:00
FreeScout
0dbdf401eb Merge branch 'master' of github.com:freescout-helpdesk/freescout into dist 2024-04-12 11:20:10 -07:00
FreeScout
db84078093 v1.8.134 2024-04-12 11:19:57 -07:00
FreeScout
a0ab8069d2 Fix Header::decode() is not supported error in Webklex/php-imap - closes #3960 2024-04-12 11:18:45 -07:00
FreeScout
ea068dc23e Update Readme 2024-04-11 23:33:16 -07:00
FreeScout
26756cc687 Add vendor files to dist 2024-04-11 23:17:54 -07:00
FreeScout
171a4e3b48 Merge branch 'master' of github.com:freescout-helpdesk/freescout into dist 2024-04-11 23:17:21 -07:00
FreeScout
bfd5aef4d9 v1.8.133 2024-04-11 23:17:11 -07:00
FreeScout
b3c2a48eec Fix an error when new conversation draft is being discarded by other user - closes #3951 2024-04-11 23:15:26 -07:00
FreeScout
848cc9e43f Fix To field not appearing after discarding forwarding draft - closes #3950 2024-04-10 23:10:27 -07:00
FreeScout
f61230ff35 Update Polish translation 2024-04-10 22:54:15 -07:00
FreeScout
268740a142 Fix an issue with removing attachments when replying 2024-04-10 06:40:48 -07:00
FreeScout
abf8d32ff5 When forwarding a conversation do not include attachments from drafts 2024-04-10 06:39:15 -07:00
FreeScout
b769aec7e8 Fix attachments not being sent when forwarding a conversation 2024-04-10 06:29:10 -07:00
FreeScout
84832f011a Fix attachments being duplicated when discarding forwarding draft - closes #3949 2024-04-10 06:28:34 -07:00
FreeScout
b1dc766ffb Make updates in Webklex/php-imap library 2024-04-10 05:35:06 -07:00
FreeScout
3274b35468 Do not mark thread as containing attachments when only embedded images are present in the email 2024-04-09 07:06:47 -07:00
FreeScout
ad76e2d3ce Merge branch 'master' of github.com:freescout-helpdesk/freescout into dist 2024-04-09 03:19:17 -07:00
FreeScout
aec78d147a v1.8.132 2024-04-09 03:19:03 -07:00
FreeScout
9333111a99 Fix some emails shown incorrectly - closes #3907 2024-04-08 11:21:52 -07:00
FreeScout
1f0d192fd5 Fix Call to a member function getFullName() on null error in notification template - closes #3942 2024-04-07 09:27:04 -07:00
FreeScout
21f04259cb Fix Call to a member function getFullName() on null error in notification template - closes #3942 2024-04-07 09:10:29 -07:00
FreeScout
a62eb20f26 Update ru.json 2024-04-06 23:16:01 -07:00
FreeScout
b813a4af9d Update ru.json #3945 from ViktorOn/master
Update ru.json
2024-04-07 08:51:13 +03:00
Vik
09ca411903 Update ru.json
Lots of edits
2024-04-07 00:37:14 +03:00
FreeScout
59c256f8cc Fix duplicated folder names when getting IMAP folders - closes #3937 2024-04-05 07:15:56 -07:00
FreeScout
c0e2a8a6fb Fix Passing null error in symfony/http-foundation/Request.php - closes #3940 2024-04-05 04:23:26 -07:00
FreeScout
c15278d3c6 Merge branch 'master' of github.com:freescout-helpdesk/freescout into dist 2024-04-04 22:21:07 -07:00
FreeScout
7cf3c67432 v1.8.131 2024-04-04 22:20:55 -07:00
FreeScout
1ef3796709 Fix attachment IDs when checking max message size - closes #3939 2024-04-04 11:24:33 -07:00
FreeScout
d3527f2aee Allow limiting command freescout:fetch-emails to specific mailboxes #3932 from ohader/fetch-emails-mailbox
Allow limiting command freescout:fetch-emails to specific mailboxes
2024-04-03 21:10:58 +03:00
Oliver Hader
31b3dff98e Allow limiting command freescout:fetch-emails to specific mailboxes
This change introduces an optional command option `mailboxes`, which
can be used to limit fetching messages to particular mailbox ids.

The following example fetches all messages of the last 500 days
for the specific mailboxes 5 and 7 only. By omitting the new
`mailboxes` option, any message of any mailbox would have been fetched.

```
php artisan freescout:fetch-emails --mailboxes=5,7 --unseen=0 --days=500
```
2024-04-03 20:06:51 +02:00
FreeScout
1b9cf02f1a Fix saving into Sent IMAP folder message with attachments - closes #3934 2024-04-03 10:06:38 -07:00
FreeScout
a9963c2f43 Fix saving into Sent IMAP folder message with attachments - closes #3934 2024-04-03 01:19:22 -07:00
FreeScout
b9bdf92065 Update Polish translation 2024-04-01 23:05:26 -07:00
FreeScout
b66b8f1880 Fix To and From headers when saving outgoing emails to the Sent IMAP folder - closes #3900 2024-04-01 23:04:01 -07:00
FreeScout
356b211754 Allow fetching seen/read messages via scheduler #3931 from ohader/schedule-fetch-unseen
Allow fetching seen/read messages via scheduler
2024-04-02 08:48:26 +03:00
FreeScout
833389c1fc Fix retrieving IMAP subfolders - closes #3933 2024-04-01 22:46:13 -07:00
Oliver Hader
f5e30cdff3 Allow fetching seen/read messages via scheduler
Usually the `schedule:run` command invokes `freescout:fetch-emails`,
but only fetches unseen (not read by anybody else, yet). This change
allows to configure this behavior and to fetch seen/read messages.

The new option `app.fetch_unseen` can be configured via `.env`:

```
APP_FETCH_UNSEEN=0
```
2024-04-01 14:54:58 +02:00
FreeScout
50f6cd743a Make params optional in Helper::setGuzzleDefaultOptions() #3926 from Lars-/master
Make params optional in Helper::setGuzzleDefaultOptions()
2024-03-30 08:10:49 +03:00
Lars Jansen
c4c6e861b5 fix: optional params in setGuzzleDefaultOptions 2024-03-30 06:02:34 +01:00
FreeScout
cac293b75b Use encrypted attachment IDs when uploading attachments 2024-03-29 09:37:56 -07:00
FreeScout
2c39ba9d9e Merge branch 'master' of github.com:freescout-helpdesk/freescout into dist 2024-03-29 07:36:35 -07:00
FreeScout
a1602fa57a v1.8.130 2024-03-29 07:36:25 -07:00
FreeScout
f6f1adc9f4 Use encrypted attachment IDs when uploading attachments 2024-03-29 07:35:38 -07:00
FreeScout
9fbbba817e Fix conv_type_custom error - closes #3923 2024-03-29 07:34:49 -07:00
FreeScout
d973a8a2ca Update Japanese translation 2024-03-29 06:41:48 -07:00
FreeScout
70cc044e57 Merge branch 'master' of github.com:freescout-helpdesk/freescout into dist 2024-03-29 06:36:58 -07:00
FreeScout
f7498e5ba2 v1.8.129 2024-03-29 06:36:06 -07:00
FreeScout
e103599984 Helper encrypt and decypt with password functions 2024-03-29 06:34:40 -07:00
FreeScout
40abe0b311 Update Japanese translation 2024-03-28 23:02:19 -07:00
FreeScout
8b9e514ce9 Add Custom conversation type #3918 from Lars-/master
Add Custom conversation type
2024-03-28 11:26:34 +03:00
Lars Jansen
582f3a6ae4 feat: new conversation type: custom 2024-03-28 09:08:41 +01:00
Lars Jansen
5589c0a80f Merge remote-tracking branch 'Github/master' 2024-03-28 09:08:10 +01:00
FreeScout
71c67ad637 Re-sort strings in translation files 2024-03-26 23:07:15 -07:00
FreeScout
1c7aff0d5b Fix deleting conversations after sorting them - closes #3901 2024-03-25 23:50:32 -07:00
FreeScout
9b359abcce Add sender name to From field when saving email to the Sent folder - closes #3900 2024-03-25 00:24:28 -07:00
FreeScout
67de1109fe Add vendor files to dist 2024-03-22 00:11:37 -07:00
FreeScout
3489567cde Merge branch 'master' of github.com:freescout-helpdesk/freescout into dist 2024-03-22 00:11:04 -07:00
FreeScout
d69e6c3501 v1.8.128 2024-03-22 00:10:55 -07:00
FreeScout
01dec5160e Exclude duplicate INBOX. folders when retreiving folders 2024-03-21 23:40:54 -07:00
FreeScout
90c80c9946 Fix removing comments when purifying HTML - closes #3894 2024-03-21 02:48:15 -07:00
FreeScout
0b9ca610b7 Fix Passing null to parameter error in HTMLPurifier - closes #3893 2024-03-20 23:07:07 -07:00
FreeScout
2a2782bc95 Fix conversations bulk actions when page parameter is set in the URL 2024-03-19 23:18:02 -07:00
FreeScout
3b6b02ed19 Fix conversation bulk actions after sorting conversations - closes #3884 2024-03-19 23:08:38 -07:00
FreeScout
443ae7f40b Fix long fetch command being killed - closes #3844 2024-03-19 06:45:05 -07:00
FreeScout
4c91ac44e1 Sanitize Path to PHP in tools.php 2024-03-19 04:47:43 -07:00
FreeScout
42dc98fa45 Strip script tags from mailbox signature 2024-03-19 03:15:37 -07:00
FreeScout
e88bec86fb Merge branch 'master' of github.com:freescout-helpdesk/freescout into dist 2024-03-18 00:25:56 -07:00
FreeScout
20c8ef7383 v1.8.127 2024-03-18 00:25:48 -07:00
FreeScout
ff09db6244 Upgrade DataTables to 1.13.11 2024-03-18 00:11:45 -07:00
FreeScout
c15a00d603 Properly process situation when an attachment can not be saved to the disc - closes #3871 2024-03-13 07:14:24 -07:00
FreeScout
b18cf31bdc Show extended editor toolbar when editing threads - closes #3866 2024-03-12 00:37:51 -07:00
FreeScout
3ee1a96bde Allow <center> element when purifying thread content 2024-03-12 00:27:39 -07:00
FreeScout
8c470d0e4e Remove [if mso] from thread content when purifying 2024-03-12 00:26:43 -07:00
FreeScout
0826102f6e Preserve elements inside [if mso] when purifying thread content 2024-03-12 00:13:27 -07:00
FreeScout
2ff52a0359 Use latest PHP version for linting #3864 from fulldecent/patch-15
Use latest PHP version for linting
2024-03-12 09:54:41 +03:00
William Entriken
8d70999498 Use latest PHP version for linting 2024-03-10 13:25:44 -04:00
FreeScout
f6a4581dad Merge branch 'master' of github.com:freescout-helpdesk/freescout into dist 2024-03-08 06:49:51 -08:00
FreeScout
2d74977ed3 v1.8.126 2024-03-08 06:49:39 -08:00
FreeScout
8b06724b67 Fix an issue with updating modules 2024-03-08 06:48:51 -08:00
FreeScout
c4755fa920 Disable Undo reply feature for chat conversations in Chat Mode - closes #3856 2024-03-08 06:17:44 -08:00
FreeScout
36f146a71d Merge branch 'master' of github.com:freescout-helpdesk/freescout into dist 2024-03-08 01:17:16 -08:00
FreeScout
a5515d8520 v1.8.125 2024-03-08 01:16:49 -08:00
FreeScout
33514c6e25 Fixed an issue with opening Closed folder - closes #3858 2024-03-08 01:16:14 -08:00
FreeScout
d8a582aaa5 Merge branch 'master' of github.com:freescout-helpdesk/freescout into dist 2024-03-08 00:23:41 -08:00
FreeScout
a428d33964 v1.8.124 2024-03-08 00:23:25 -08:00
FreeScout
33639a8955 Merge branch 'master' of github.com:freescout-helpdesk/freescout into dist 2024-03-08 00:09:52 -08:00
FreeScout
4021f07aec v1.8.123 2024-03-08 00:09:43 -08:00
FreeScout
67bd456b63 Update Readme 2024-03-07 22:08:26 -08:00
FreeScout
78cc5877a3 Update readme 2024-03-07 10:43:17 -08:00
FreeScout
c4bc505e03 Accessibility of exact date in conversation table - closes #3829 2024-03-07 10:41:43 -08:00
FreeScout
ad372590a9 Allowing updates for third party modules #3851 from Lars-/master
Allowing updates for third party modules
2024-03-07 13:35:03 +03:00
Lars Jansen
2771d526be chore: added comments 2024-03-07 11:24:04 +01:00
Lars Jansen
263ec4d266 fix: code styling 2024-03-07 11:03:46 +01:00
FreeScout
f86876328e Accessibility of exact date in conversation table - closes #3829 2024-03-06 21:55:33 -08:00
Lars Jansen
e47167b17e feat: allow updates for external modules 2024-03-05 20:46:43 +01:00
Lars Jansen
5c32cf69e6 fix: typo 2024-03-05 15:39:31 +01:00
Lars Jansen
fd46017c45 feat: add author to module card if available 2024-03-05 15:39:26 +01:00
FreeScout
95d3cca660 Do not save SMTP username and password in Send Log status message 2024-03-05 06:39:24 -08:00
FreeScout
1fcb5560f0 Fix Passing null to parameter error in Helper::stripTags() - closes #3849 2024-03-05 01:30:31 -08:00
FreeScout
06b3dc27d2 Fix creating conversations by a user seeing only assigned conversations - closes #3843 2024-03-04 05:36:57 -08:00
FreeScout
d2b683368c If user can see only assigned conversations send him notifications only for assigned to him conversations - closes #3843 2024-03-02 21:32:19 -08:00
FreeScout
6b397ccd3f Fix creating conversations by a user seeing only assigned conversations - closes #3843 2024-03-02 21:09:50 -08:00
FreeScout
32006fe8e1 Fix adding notes to Spam conversations 2024-03-02 04:58:52 -08:00
FreeScout
911e157322 Fix showing only assigned to the user tickets - closes #3843 2024-03-02 04:44:23 -08:00
FreeScout
100b4062bf Fix Numeric value out of range error in search on PostgreSQL - closes #3831 2024-02-27 23:04:44 -08:00
FreeScout
b27e2b7a1c Update Czech translation 2024-02-24 06:50:52 -08:00
FreeScout
7085009667 Update Spanish translation 2024-02-24 06:24:34 -08:00
FreeScout
4b6ceab070 Fix word plus colon mistakenly converted to URL in editor - closes #3822 2024-02-24 03:54:38 -08:00
FreeScout
49af472617 Merge branch 'master' of github.com:freescout-helpdesk/freescout into dist 2024-02-23 06:52:13 -08:00
FreeScout
d7aeb0d3b3 v1.8.122 2024-02-23 06:52:03 -08:00
FreeScout
35f8b775f9 Fix an issue with minify.config.php - closes #3818 2024-02-23 06:49:37 -08:00
FreeScout
079df0d6a6 Merge branch 'master' of github.com:freescout-helpdesk/freescout into dist 2024-02-23 03:26:42 -08:00
FreeScout
36442cb3a2 v1.8.121 2024-02-23 03:26:32 -08:00
FreeScout
217cd9183e Add Turkish language 2024-02-20 03:12:36 -08:00
FreeScout
e9c2eaebce Fix showing scaled image in threads - closes #3798 2024-02-20 03:00:48 -08:00
FreeScout
954c790827 Update it.json #3755 from PeopleInside/patch-1
Update it.json
2024-02-20 11:53:55 +03:00
FreeScout
2d2b476688 Remove APP_URL from minify.config.php to avoid CORS issues on custom domains 2024-02-20 00:21:20 -08:00
FreeScout
ab58217cab Improve sorting elements on mobile devices - closes #3800 2024-02-18 22:29:13 -08:00
FreeScout
6f0b05c1f6 Improve searching customers by phone number when creating Phone conversations - closes #3786 2024-02-18 08:54:17 -08:00
FreeScout
58d35098c0 Allow to set session.same_site via SESSION_SAME_SITE env parameter - closes #3023 2024-02-18 05:54:38 -08:00
FreeScout
44e71e58e6 Remove 255 symbols limit from mailbox Alises 2024-02-18 05:36:30 -08:00
FreeScout
0e516bc407 Allow style attribute for tr in HTML purifier - closes #3799 2024-02-18 05:28:06 -08:00
Marco Borla
9fc7b9d755 Update it.json
Fix Soggetto is Oggetto.

Subject = Oggetto
2024-02-02 10:46:40 +01:00
FreeScout
e1ff8fb520 Merge branch 'master' of github.com:freescout-helpdesk/freescout into dist 2024-02-01 17:35:42 -08:00
FreeScout
adf308ac9f v1.8.120 2024-02-01 17:35:31 -08:00
FreeScout
7b6abe858c Fix an issue with multiple emails being sent to customers - closes #3632 2024-01-31 23:17:48 -08:00
FreeScout
6937346e5a Show .parsley-required in red color 2024-01-31 23:10:08 -08:00
FreeScout
fc1a354072 Update Italian translation #3739 from floatingpurr/fix-transalation
✨ Update Italian translation
2024-01-26 19:41:15 +03:00
Andrea Mignone
82464e4129 ✨ Modify Italian translation 2024-01-26 15:29:04 +01:00
FreeScout
1a126ad743 Add parameter to open tracking URL 2024-01-26 06:01:43 -08:00
FreeScout
9558194bf7 Fix redeclaration of let DragDropTouch on Translate page - closes #3717 2024-01-26 00:51:00 -08:00
FreeScout
8aa2f0c018 Improve contrast on on unread notifications 2024-01-24 22:26:11 -08:00
FreeScout
d6de310363 Improve contrast on on unread notifications #3728 from mokkin/patch-1
Improve contrast on on unread notifications
2024-01-25 09:17:59 +03:00
mokkin
1fdddb25ec improve contrast on on unread notifications
fixes https://github.com/freescout-helpdesk/freescout/issues/3693
2024-01-23 17:15:15 +01:00
FreeScout
a78f6f5ce3 Add vendor files to dist 2024-01-23 02:01:04 -08:00
FreeScout
2528727d81 Merge branch 'master' of github.com:freescout-helpdesk/freescout into dist 2024-01-23 02:00:40 -08:00
FreeScout
97bb4dd956 v1.8.119 2024-01-23 02:00:23 -08:00
FreeScout
3c6819c9e7 Fix scrolling conversations list on mobile devices - closes #3724 2024-01-23 01:59:33 -08:00
FreeScout
bb2fc15c07 Fix error in HTMLPurifier/Length.php - closes #3721 2024-01-23 00:45:39 -08:00
FreeScout
fb129df215 Fix Bootstrap submenu after applying DragDropTouch Polyfill - closes #3708 2024-01-22 01:05:29 -08:00
FreeScout
050ccb921e Fix Trailing data error on PostgreSQL - closes #3702 2024-01-20 22:05:39 -08:00
FreeScout
9b9aae4c0e Add vendor files to dist 2024-01-19 23:40:40 -08:00
FreeScout
263569b163 Merge branch 'master' of github.com:freescout-helpdesk/freescout into dist 2024-01-19 23:40:11 -08:00
FreeScout
2702232eea v1.8.118 2024-01-19 23:40:02 -08:00
FreeScout
8f802b4d38 Update install.sh 2024-01-19 23:38:24 -08:00
FreeScout
00b4aabb32 Update Slovak translation #3692 from jozefrebjak/sk-lang-update
Update Slovak translation
2024-01-20 10:31:24 +03:00
Jozef Rebjak
8ea84dca94 lang: update slovak translation 2024-01-16 15:02:22 +01:00
FreeScout
bc45b779ef Fix Use of undefined constant FT_UID in Webklex/laravel-imap - closes #2604 2024-01-15 19:06:51 -08:00
FreeScout
c72286623f Fix Use of undefined constant FT_UID in Webklex/laravel-imap - closes #2604 2024-01-11 21:56:49 -08:00
FreeScout
1d3c97fae5 Do not show Delete button in bulk actions if user does not have corresponding permission - closes #3680 2024-01-11 10:35:19 -08:00
FreeScout
17e22b8b93 Improve HTML purification - closes #3664 2024-01-11 10:24:46 -08:00
FreeScout
e32714ebaf Make html5sortable.js work on mobile devices - closes #3671 2024-01-09 23:33:53 -08:00
FreeScout
acd81548e6 Make summernote compatible with jQuery v3.6.0 - closes #3666 2024-01-08 09:23:07 -08:00
FreeScout
2d71860fa1 Fix counter not aligned in Dashboard - closes #3665 2024-01-08 04:16:19 -08:00
FreeScout
6930924cc1 Update German translation 2024-01-06 21:02:28 -08:00
FreeScout
e5ce253daf Merge branch 'master' of github.com:freescout-helpdesk/freescout into dist 2024-01-06 04:08:07 -08:00
FreeScout
b9cfe0e300 v1.8.117 2024-01-06 04:07:56 -08:00
FreeScout
af91c8c9e3 Fix Call to undefined method getHashedRelySeparator() 2024-01-06 04:06:14 -08:00
FreeScout
08e50e3643 Localize calendar 2024-01-06 03:55:51 -08:00
FreeScout
885001ec97 Merge branch 'master' of github.com:freescout-helpdesk/freescout into dist 2024-01-05 20:47:49 -08:00
FreeScout
b2dae09cf1 Improve fetching email in Show Original window - closes #3658 2024-01-05 10:08:21 -08:00
FreeScout
c55d94d969 Add alternative reply separation method - closes #3648 2024-01-05 08:35:15 -08:00
FreeScout
7d035f5604 Merge branch 'master' of github.com:freescout-helpdesk/freescout into dist 2024-01-05 08:20:36 -08:00
FreeScout
a5f49080a7 v1.8.116 2024-01-05 08:20:21 -08:00
FreeScout
8a52a85ca3 Replace shell_exec() with Helper::shellExec() 2024-01-05 03:28:30 -08:00
FreeScout
2bfdc99f89 Add alternative reply separation method - closes #3648 2024-01-04 02:03:36 -08:00
FreeScout
e5da621736 Copy attachments when creating a new conversation from some message - closes #3647 2024-01-03 23:57:07 -08:00
FreeScout
359f6c455c Add alternative reply separation method - closes #3648 2024-01-03 22:22:59 -08:00
FreeScout
e929af5c99 Upgrade Bootstrap to v3.4.1 2024-01-03 03:17:36 -08:00
FreeScout
191e61400d Upgrade jQuery to v3.6.0 2024-01-03 03:15:52 -08:00
FreeScout
d311b40faa Allow to filter conversation by Assignee - closes #3641 2024-01-02 03:31:34 -08:00
FreeScout
7c7fc41b2c Add America/Santiago timezone - closes #3639 2023-12-31 07:48:11 -08:00
FreeScout
5ab0f84d41 Refine the Italian translation #3634 from floatingpurr/fix-translation
Refine the Italian translation
2023-12-27 20:44:16 +03:00
Andrea Mignone
5917b190eb Refine and make consistent Italian translation 2023-12-27 18:40:18 +01:00
FreeScout
828c7b814c Show SMTP communication details when testing mail sending - closes #3626 2023-12-27 02:12:06 -08:00
FreeScout
6d3f1bbee8 Show SMTP communication details when testing mail sending - closes #3626 2023-12-27 01:04:03 -08:00
FreeScout
85954ab7cc Add vendor files to dist 2023-12-26 21:49:22 -08:00
FreeScout
822b2f4ae7 Merge branch 'master' of github.com:freescout-helpdesk/freescout into dist 2023-12-26 21:48:38 -08:00
FreeScout
ed6911a8dc v1.8.115 2023-12-26 21:30:05 -08:00
FreeScout
d8cfe15373 Improve linkify algorithm 2023-12-23 01:50:22 -08:00
FreeScout
dc4d6d2671 Add StartTLS encryption option for Fetching Email when Webklex/php-imap is used - closes #3624 2023-12-22 03:27:03 -08:00
FreeScout
eb6b30864f Improve the message shown when IMAP folder can not be found during fetching 2023-12-22 00:25:26 -08:00
FreeScout
1618bb1266 Allow to fetch emails from nested folders - closes #3623 2023-12-21 23:11:39 -08:00
FreeScout
54e5aa28bd Do not set customer last name when it was manually removed - closes #3622 2023-12-21 00:55:22 -08:00
FreeScout
4e72e2ea50 Fix null error in locale_options template - closes #3620 2023-12-20 03:41:08 -08:00
FreeScout
134608625f Fix Packets out of order error - closes #3619 2023-12-20 03:34:55 -08:00
FreeScout
11fbaa6be8 Merge branch 'master' of github.com:freescout-helpdesk/freescout into dist 2023-12-19 21:59:34 -08:00
FreeScout
377dd08c96 v1.8.114 2023-12-19 21:59:03 -08:00
FreeScout
6a9dfe6dd1 Fix email send loop - closes #3607 2023-12-19 21:30:02 -08:00
FreeScout
59da4e4f99 Fix email send loop - closes #3607 2023-12-19 09:37:58 -08:00
FreeScout
6d917f82d7 Add as CC a customer who was in CC and replied to the conversation - #3613 2023-12-16 21:15:02 -08:00
FreeScout
15780467eb Do not strip HTML tags in plain text emails - closes #3614 2023-12-16 04:09:15 -08:00
FreeScout
1a53871517 Merge branch 'master' of github.com:freescout-helpdesk/freescout into dist 2023-12-14 23:58:28 -08:00
FreeScout
ef0af3a494 v1.8.113 2023-12-14 23:58:15 -08:00
FreeScout
ab854befd1 Helper::sanitizeDatepickerDatetime() function 2023-12-14 21:58:12 -08:00
FreeScout
3d522c4f2e Show notice on System Status page is CloudFlare is used 2023-12-13 09:32:18 -08:00
FreeScout
7908da3721 Allow to translate English texts - closes #3599 2023-12-13 06:00:12 -08:00
FreeScout
f9a3354741 Fix user reply to a notification being incorrectly cropped - closes #3580 2023-12-12 09:57:03 -08:00
FreeScout
fbf4d3b355 Improve SendReplyToCustomer background jobs monitoring - closes #3590 2023-12-12 03:43:31 -08:00
FreeScout
f1839bcfbf Fix user reply to a notification being incorrectly cropped - closes #3580 2023-12-11 10:23:17 -08:00
FreeScout
895af2d7ad Make sure thread_id is null for an attachment when linking attachment to a thread 2023-12-11 06:09:38 -08:00
FreeScout
b5510da291 Do not remove double dots from attachment names - closes #3592 2023-12-09 10:40:25 -08:00
FreeScout
3083738d00 Merge branch 'master' of github.com:freescout-helpdesk/freescout into dist 2023-12-08 02:45:34 -08:00
FreeScout
ea84fe82dd v1.8.112 2023-12-08 02:45:08 -08:00
FreeScout
ea8b7507e4 Merge branch 'master' of github.com:freescout-helpdesk/freescout into dist 2023-12-07 23:35:26 -08:00
FreeScout
7dfd170983 Allow .PEM insertion for MySQL connections #3582 from crixle/master
Allow .PEM insertion for MySQL connections
2023-12-06 11:53:58 +03:00
Crixle
06c7e709e6 Allow .PEM insertion for MySQL connections
Required for PaaS DB servers that require SSL.
2023-12-05 17:22:06 -05:00
FreeScout
e0f10670d7 Improve linkify algorithm - closes #3402 2023-12-03 02:27:03 -08:00
FreeScout
b33d2dff4a Fix Call to undefined function shell_exec() on Status page - closes #3570 2023-12-02 21:32:27 -08:00
FreeScout
2f1b9ebe0c conversation.is_user_assignee hook - closes #3568 2023-12-02 04:18:52 -08:00
FreeScout
9b024bda31 Do not change customer when CCed email replies to a conversation - closes #3551 2023-12-02 00:46:47 -08:00
FreeScout
606dcf17c9 Merge branch 'master' of github.com:freescout-helpdesk/freescout into dist 2023-12-01 21:20:17 -08:00
FreeScout
2fb0c29705 v1.8.110 2023-12-01 21:20:07 -08:00
FreeScout
d673a7006b Fix Select None button - closes #3546 2023-11-24 21:11:49 -08:00
FreeScout
fbe3a795df Merge multiple conversations at once - closes #3516 2023-11-23 23:04:51 -08:00
FreeScout
0c614c3f7e Make error message in logs more descriptive when SendReplyToCustomer job can not save outgoing reply to the IMAP folder 2023-11-22 23:52:36 -08:00
FreeScout
ce4bebb8b4 Autosave new conversation draft when choosing recipient - closes #3538 2023-11-22 21:23:15 -08:00
FreeScout
a8b4a581e4 Update Readme 2023-11-21 23:21:39 -08:00
FreeScout
7d5cc80898 Update readme 2023-11-21 23:18:19 -08:00
FreeScout
7fa6003156 Update Portuguese translation 2023-11-21 21:47:51 -08:00
FreeScout
87cdff17b8 Improve linkify algorithm - closes #3402 2023-11-19 23:06:52 -08:00
FreeScout
4fbe3a3340 Allow to select multiple conversations using SHIFT button - closes #1312 2023-11-19 22:02:36 -08:00
FreeScout
c2a8894d9f Dynamically load customer info when creating new conversation - closes #2402 2023-11-18 04:02:19 -08:00
FreeScout
4bb7e224d7 Show customer info when opening new conversation draft - closes #2402 2023-11-18 01:02:00 -08:00
FreeScout
c24efff92f Check pcntl_signal() function on System Status page in the console PHP 2023-11-17 22:28:01 -08:00
FreeScout
9dc73c29ff Set min-height for .container 2023-11-17 22:16:21 -08:00
FreeScout
c2d599b546 Merge branch 'master' of github.com:freescout-helpdesk/freescout into dist 2023-11-17 21:20:09 -08:00
FreeScout
574d1d1d69 v1.8.109 2023-11-17 21:19:57 -08:00
FreeScout
f3ff95cc57 Allow to set SMTP timeout via MAIL_SMTP_TIMEOUT .env parameter 2023-11-17 05:30:47 -08:00
FreeScout
4a2f4fdadc Allow to set SMTP timeout via MAIL_TIMEOUT .env parameter 2023-11-16 21:56:58 -08:00
FreeScout
c2bd39a65f Mark email as read when saving to IMAP Folder with Webklex/PHPIMAP - closes #3533 2023-11-16 10:54:52 -08:00
FreeScout
529b141f1b Fix URLs for attachments with percents - closes #3530 2023-11-15 21:16:46 -08:00
FreeScout
de643ee51b Remove max length limitation from mailbox Aliases field - closes #3525 2023-11-13 22:01:59 -08:00
FreeScout
1dd59bc2b6 Fix displaying SVG images in the uploaded folder on Apache - closes #3522 2023-11-12 22:45:55 -08:00
FreeScout
8b80bd4119 Allow to set table prefix via .env DB_TABLE_PREFIX parameter - closes #3523 2023-11-12 22:23:13 -08:00
FreeScout
0ca0ea0e93 Check pcntl_signal() function on System Status page - closes #3515 2023-11-12 22:18:54 -08:00
FreeScout
4f15b2f273 Allow to retry thread sending from conversation - closes #3517 2023-11-09 05:31:47 -08:00
FreeScout
63e2384907 PHP IMAP: Only explode the tag line if it contains a space - closes #3503 2023-11-08 09:21:41 -08:00
FreeScout
e9b66ff7fd Allow to pass custom message to \Helper::denyAccess() 2023-11-08 09:21:15 -08:00
FreeScout
0eff48267f Fix cicle between two tickets with older newer buttons - closes #3506 2023-11-07 22:04:53 -08:00
FreeScout
4c9f247cf6 Merge branch 'master' of github.com:freescout-helpdesk/freescout into dist 2023-11-06 23:50:12 -08:00
FreeScout
5aa7552232 v1.8.108 2023-11-06 23:49:59 -08:00
FreeScout
0dd1a7308a Fixed saving outgoing replies to the IMAP Sent folder with non-ASCII name 2023-11-06 23:48:51 -08:00
FreeScout
315aeafd24 Fix fetching emails from non-ascii imap folders - closes #3502 2023-11-06 23:33:47 -08:00
FreeScout
74fd2dcf5e Fix Passing null to parameter error in User.php - closes #3501 2023-11-06 05:20:33 -08:00
FreeScout
da66ab2fc6 Add html5sortable.js script 2023-11-04 21:49:58 -07:00
FreeScout
4835fba6dc Fix an issue with phone customers always shown in the search - closes #3499 2023-11-04 05:02:48 -07:00
FreeScout
c28b663f56 Merge branch 'master' of github.com:freescout-helpdesk/freescout into dist 2023-11-03 23:48:43 -07:00
FreeScout
cc2ece53ee v1.8.107 2023-11-03 23:48:35 -07:00
FreeScout
ccc23e6e52 Update install.sh 2023-11-03 23:47:50 -07:00
FreeScout
cee5c16aa1 Adjust installer styles 2023-11-03 23:34:05 -07:00
FreeScout
84db98515d Make install.sh script compatible with Debian 2023-11-03 23:33:48 -07:00
FreeScout
4a24df3395 Fix installing helpdesk without HTTPS via install.sh script 2023-11-03 23:33:10 -07:00
FreeScout
f21054f17f Helper::sqlSanitizeString() function 2023-11-03 03:13:10 -07:00
FreeScout
e12824008f Update general_help_request.md 2023-11-01 10:45:00 -07:00
FreeScout
0c24e04b8c Improve font color sanitizing when purifying thread content - closes #3492 2023-11-01 10:23:33 -07:00
FreeScout
e66aae1209 Set max length for attribtues before saving a user to avoid String data right truncated error on PostgreSQL - closes #3489 2023-11-01 06:07:03 -07:00
FreeScout
e652a1eced Set system timezone by default for users created outside of web interface - closes #3490 2023-10-31 23:20:44 -07:00
FreeScout
bbfbd43105 Fix incorrect redirect when replying to the last active conversation - closes #3486 2023-10-31 07:10:05 -07:00
FreeScout
62bc9643fd .link-grey-blue style 2023-10-31 07:08:24 -07:00
FreeScout
a36bbb2ffa Update Polish translation 2023-10-31 00:31:28 -07:00
FreeScout
c58e2403ca Add dashboard.heading_append hook 2023-10-28 22:07:23 -07:00
FreeScout
926327156d Dynamically expand Logs Monitoring settings in Alerts 2023-10-27 22:19:32 -07:00
FreeScout
45a7f9ae65 Merge branch 'master' of github.com:freescout-helpdesk/freescout into dist 2023-10-27 01:22:55 -07:00
FreeScout
26536b965c v1.8.106 2023-10-27 01:22:47 -07:00
FreeScout
896de29721 Add Max Message Size option to General Settings - closes #3479 2023-10-26 02:01:17 -07:00
FreeScout
fdafd95584 Fix: support overriding of viewable attachments from .env #3481 from InteractiveWebdesign/patch-1
Fix: support overriding of viewable attachments from .env
2023-10-26 10:42:53 +03:00
Interactive-Webdesign
e0f31775e5 fix: support overriding of viewable attachments from .env 2023-10-26 09:38:49 +02:00
FreeScout
67a67aef88 Show All from current mailbox link in conversations - closes #3480 2023-10-25 22:19:41 -07:00
FreeScout
0c28152d43 Fix multiplying attachments when forwarding a conversation 2023-10-24 22:20:46 -07:00
FreeScout
a361b3ba41 Fetch emails into several mailboxes when customer replies - closes #3473 2023-10-24 11:12:56 -07:00
FreeScout
20fe99a820 Fix multiplying attachments when forwarding a conversation 2023-10-23 22:58:40 -07:00
FreeScout
d380d5dd0e Merge branch 'master' of github.com:freescout-helpdesk/freescout into dist 2023-10-22 23:41:30 -07:00
FreeScout
7df8b05e00 v1.8.105 2023-10-22 23:41:23 -07:00
FreeScout
7708fa86bd Allow to set APP_CLOUDFLARE_IS_USED=true for proper client IP detection when CloudFlare is used - closes #3467 2023-10-22 23:34:01 -07:00
FreeScout
ccb865821d Improve converting URLs into clickable links - closes #3464 2023-10-18 01:41:35 -07:00
FreeScout
7ff10f5510 Allow more attributes when purifying HTML - closes #3463 2023-10-18 00:58:33 -07:00
FreeScout
fce9f83459 Add X-Frame-Options header 2023-10-17 23:20:30 -07:00
FreeScout
74609b0705 Add client_max_body_size to nginx config in install.sh - closes #3453 2023-10-15 00:52:43 -07:00
FreeScout
5efc10ede6 Chat Mode 2023-10-14 06:38:55 -07:00
FreeScout
99bab479e0 Fix an issue when support agent replies to the email notifications and conversation moved to another mailbox - closes #3455 2023-10-12 23:15:16 -07:00
FreeScout
70f11046f1 Merge branch 'master' of github.com:freescout-helpdesk/freescout into dist 2023-10-12 21:54:05 -07:00
FreeScout
6094bddf6a v1.8.104 2023-10-12 21:53:43 -07:00
FreeScout
490d571f3c Add icon to chat conversations tag 2023-10-12 01:50:03 -07:00
FreeScout
18dc66f319 Update install.sh 2023-10-10 00:05:24 -07:00
FreeScout
ba174ed435 Fix apache headers module not found - closes #3450 2023-10-09 22:29:59 -07:00
FreeScout
33723056ec Merge branch 'master' of github.com:freescout-helpdesk/freescout into dist 2023-10-08 11:11:13 -07:00
FreeScout
5f9c615ac5 v1.8.103 2023-10-08 11:11:04 -07:00
FreeScout
76b3776d79 Fix CSP error on module install - closes #3445 2023-10-08 11:09:51 -07:00
FreeScout
b3f2cddd2d Merge branch 'master' of github.com:freescout-helpdesk/freescout into dist 2023-10-07 22:02:17 -07:00
FreeScout
d9dac047a0 v1.8.102 2023-10-07 22:01:58 -07:00
FreeScout
a863377597 Enable Content Security Policy 2023-10-07 22:00:57 -07:00
FreeScout
5420cd415b Do not add paperclip to conversations when email contains only embedded images and do not show embedded images as attachments in conversations 2023-10-07 03:53:24 -07:00
FreeScout
1d79d7fe00 Save base64 data images as attachments on fetching 2023-10-05 23:44:42 -07:00
FreeScout
fa6bc246de Add vendor files to dist 2023-10-04 22:20:25 -07:00
FreeScout
c9d5f9f7fa Merge branch 'master' of github.com:freescout-helpdesk/freescout into dist 2023-10-04 22:18:40 -07:00
FreeScout
b0df2d6898 v1.8.101 2023-10-04 22:18:18 -07:00
FreeScout
a0f4c6b6cd Fix error in PostgreSqlPlatform.php on PHP 8.2 with PostgreSQL 2023-10-04 04:06:19 -07:00
FreeScout
309775cce2 Update test-pgsql.yml 2023-10-04 03:16:47 -07:00
FreeScout
12dcdfbf4a Update test-pgsql.yml 2023-10-04 03:05:17 -07:00
FreeScout
1fc7042545 Test Application (with PostgreSQL) 2023-10-04 03:01:23 -07:00
FreeScout
9089aba931 Update email.reply_to_customer.subject hook 2023-10-02 04:48:35 -07:00
FreeScout
b12c6102c6 Update test.yml 2023-10-02 01:04:04 -07:00
FreeScout
5548148150 Update user getAuthToken() 2023-10-01 23:48:46 -07:00
FreeScout
aff6e4acb0 CSP compatibility 2023-09-30 10:33:41 -07:00
FreeScout
1e88014f38 Configure CSP 2023-09-30 07:38:06 -07:00
FreeScout
5be74723d5 Configure CSP 2023-09-30 03:04:11 -07:00
FreeScout
f0ee5ee2ae Configure CSP 2023-09-29 09:54:13 -07:00
FreeScout
1daa34f604 Improve uploads folder security - closes #3428 2023-09-27 10:16:34 -07:00
FreeScout
258b774098 Run post update after modules in update.sh #3425 from webmaster777/post-update-after-modules
Run post update after modules in update.sh
2023-09-27 19:52:23 +03:00
FreeScout
1b6f9e4f09 Improve uploads folder security - closes #3428 2023-09-27 07:15:24 -07:00
Meindert-Jan Kroese
2598263cab run post_update.sh at the very end of updating (incl modules) 2023-09-26 14:31:04 +02:00
FreeScout
98314a9a26 Update German translation 2023-09-26 00:54:27 -07:00
FreeScout
20074845de Remove phpstan 2023-09-23 23:04:58 -07:00
FreeScout
d0b1c816eb Update lint-php.yml 2023-09-23 22:54:56 -07:00
FreeScout
5f1a59f7b3 Update phpcs and phpstan 2023-09-23 22:18:14 -07:00
FreeScout
c7644e214d Update analyse-php.yml 2023-09-23 11:40:59 -07:00
FreeScout
b6d026a2b1 Update analyse-php.yml 2023-09-23 11:37:02 -07:00
FreeScout
23c6cb33a3 Update analyse-php.yml 2023-09-23 11:29:44 -07:00
FreeScout
e68e8ef165 analyse-php.yml 2023-09-23 11:14:31 -07:00
FreeScout
912b805777 lint-js.yml 2023-09-23 11:02:51 -07:00
FreeScout
cacdf09649 lint-php.yml 2023-09-23 10:59:56 -07:00
FreeScout
b32320d59c Fix db seed error on PHP 8.2 2023-09-23 08:48:25 -07:00
FreeScout
0e2cc687d4 Rename mysql_testing DB to testing 2023-09-23 08:26:31 -07:00
FreeScout
1bc82611e9 Commit tests/Feature/ folder 2023-09-23 08:23:45 -07:00
FreeScout
6bb27b4e6f Update test.yml 2023-09-23 08:15:20 -07:00
FreeScout
3a6d5b3e34 Configure mysql_testing in database.php 2023-09-23 08:09:42 -07:00
FreeScout
33ccc85fbf Update test.yml 2023-09-23 07:47:40 -07:00
FreeScout
a21a7dbeda Update test.yml 2023-09-23 07:36:17 -07:00
FreeScout
718dc2c691 Update test.yml 2023-09-23 07:34:25 -07:00
FreeScout
7ca5a92e9f Update test.yml 2023-09-23 07:30:24 -07:00
FreeScout
7a9ecfe329 Update test.yml 2023-09-23 07:25:00 -07:00
FreeScout
ffd299f369 Update phpunit/phpunit to 9.5.28 2023-09-23 06:32:51 -07:00
FreeScout
fbf2f1f063 Add vendor files to dist 2023-09-23 03:18:04 -07:00
FreeScout
66c1ca83d9 Merge branch 'master' of github.com:freescout-helpdesk/freescout into dist 2023-09-23 03:10:53 -07:00
FreeScout
a7e542b7b2 v1.8.100 2023-09-23 03:10:22 -07:00
FreeScout
90d73053f1 Fix discarding new phone conversation draft - closes #3407 2023-09-22 23:56:37 -07:00
FreeScout
900f259620 Remove yarn.lock 2023-09-22 23:46:20 -07:00
FreeScout
b7367f89e2 Merge pull request #3408 from baldugus/master
Add filter `fetch_emails.mailbox_to_save_message`
2023-09-23 09:43:10 +03:00
FreeScout
35ba1d2ca5 Improve accessibility from philippkraft/master
Improve accessibility - addendum to issue #1150
2023-09-23 09:40:22 +03:00
FreeScout
cf072514a4 Fix OS Command Injection issue in laravel/framework 2023-09-22 23:24:08 -07:00
FreeScout
6133547617 Fix Possibility for Denial of Service by overwriting PHP files with language exports in barryvdh/laravel-translation-manager 2023-09-22 23:15:15 -07:00
FreeScout
d62bf49eb9 Fix CVE-2023-35169 issue in webklex/laravel-imap 2023-09-22 23:09:29 -07:00
FreeScout
7b32dde0cf Fix CVE-2023-35169 issue in webklex/php-imap 2023-09-22 23:04:14 -07:00
FreeScout
8c7e53aef8 Fix the issue causing long fetching process to be killed before it finishes - closes #3417 2023-09-22 21:59:00 -07:00
FreeScout
2d9e9091b4 Fix the issue causing long fetching process to be killed before it finishes - closes #3417 2023-09-22 10:48:21 -07:00
FreeScout
8363650304 Fix Cookie serialization vulnerability in laravel/framework 2023-09-22 07:06:43 -07:00
FreeScout
21d86327b9 Fix Guard bypass in Eloquent models in laravel/framework 2023-09-22 04:52:43 -07:00
FreeScout
1e871813f8 Fix CVE-2021-43808 issue in laravel/framework 2023-09-22 04:31:41 -07:00
FreeScout
822fb85f1c Fix RCE vulnerability in cookie session driver in laravel/framework 2023-09-22 02:07:50 -07:00
Philipp Kraft
ae0e931588 Merge branch 'freescout-helpdesk:master' into master 2023-09-22 10:29:24 +02:00
FreeScout
6bb91df75f Fix CVE-2019-18887 issue in symfony/http-kernel 2023-09-22 01:10:19 -07:00
FreeScout
9c1c180619 Fix CVE-2022-24894 issue in symfony/http-kernel 2023-09-22 01:01:59 -07:00
Gustavo Balduino
4b27fe0f82 Add filter fetch_emails.mailbox_to_save_message 2023-09-20 16:12:51 -03:00
FreeScout
aab5869dc9 Run test workflow on push to dist branch 2023-09-17 02:54:02 -07:00
FreeScout
c6b50b2ccf Fix CVE-2019-18888 issue in symfony/http-foundation 2023-09-17 02:49:35 -07:00
FreeScout
ba8296ef50 Fix CVE-2019-10913 issue in symfony/http-foundation 2023-09-17 01:44:45 -07:00
FreeScout
5b5df2e51e Upgrade league/flysystem to 1.1.4 2023-09-17 01:34:37 -07:00
FreeScout
73c039147e Upgrade guzzlehttp/guzzle to 6.5.8 2023-09-17 01:20:35 -07:00
FreeScout
51ef78c2af Upgrade erusev/parsedown to 1.7.2 2023-09-17 00:33:09 -07:00
FreeScout
42423bdf61 Merge branch 'master' of github.com:freescout-helpdesk/freescout into dist 2023-09-15 07:52:40 -07:00
FreeScout
35e2769ba3 Add freescout:module-update command and --yes flag to tools/update.sh - closes #3384 2023-09-15 07:52:14 -07:00
FreeScout
dc3e56d44b Merge branch 'master' of github.com:freescout-helpdesk/freescout into dist 2023-09-15 07:50:28 -07:00
FreeScout
4d59b4b463 v1.8.99 2023-09-15 07:50:00 -07:00
FreeScout
ae9f1f8b0d Update install script path in continuous integration test 2023-09-15 07:43:29 -07:00
FreeScout
e30b9ed175 Create continuous integration test #3395 from fulldecent/patch-13
Create continuous integration test
2023-09-15 17:41:19 +03:00
FreeScout
d06dbcb99d Add freescout:module-update command and --yes flag to tools/update.sh - closes #3384 2023-09-15 07:37:53 -07:00
FreeScout
70af65c51f Add tools/install.sh 2023-09-14 22:10:37 -07:00
William Entriken
d288f3319a Create continuous integration test 2023-09-14 21:43:04 -04:00
FreeScout
96b1ee7b66 Properly process situation when application can not parse mail date header - closes #3394 2023-09-14 05:51:15 -07:00
FreeScout
89b37e778a Add freescout:module-update command and --yes flag to tools/update.sh - closes #3384 2023-09-14 00:13:51 -07:00
FreeScout
a72b859f05 freescout:module-update command - closes #3384 2023-09-13 04:49:02 -07:00
FreeScout
9d1c463247 Update yarn.lock 2023-09-13 04:25:43 -07:00
FreeScout
62c7bed6bb Allow to update all modules at once 2023-09-13 01:43:56 -07:00
FreeScout
3338ea6510 App\Module::updateModule() function 2023-09-13 00:46:49 -07:00
FreeScout
b6c015e3da Remove Mail Date and Time option from Mail Settings - closes #3380 2023-09-11 22:23:22 -07:00
FreeScout
547b05dcae Update package.json 2023-09-11 22:17:20 -07:00
FreeScout
ee7a2e692b Improve attachment names sanitizing - closes #3377 2023-09-11 22:15:10 -07:00
FreeScout
d52161b44b Improve attachment names sanitizing - closes #3377 2023-09-11 10:15:55 -07:00
FreeScout
9b5bf06a29 Merge branch 'master' of github.com:freescout-helpdesk/freescout into dist 2023-09-11 09:25:25 -07:00
FreeScout
189942c45a v1.8.98 2023-09-11 09:24:40 -07:00
FreeScout
8c68731283 Skip module symlink check and creation on open_basedir restriction in effect error - closes #3375 2023-09-11 06:54:48 -07:00
FreeScout
ec24787b9b Skip module symlink check and creation on open_basedir restriction in effect error - closes #3375 2023-09-11 06:42:01 -07:00
FreeScout
c220b8be8e Set default CURLOPT_CONNECTTIMEOUT value from config 2023-09-09 06:47:20 -07:00
FreeScout
550d8cc457 Fix No query results for model error on Status page - closes #3366 2023-09-09 03:57:27 -07:00
FreeScout
2de52008a2 Merge branch 'master' of github.com:freescout-helpdesk/freescout into dist 2023-09-08 10:32:38 -07:00
FreeScout
4354742d3f v1.8.97 2023-09-08 10:32:12 -07:00
FreeScout
5e1bf39839 Fix error on System Status page - closes #3368 2023-09-08 09:50:24 -07:00
FreeScout
74ab043a30 Automatically fix module symlink when module Public folder is a broken symlink 2023-09-08 06:22:00 -07:00
FreeScout
2abe265046 Merge branch 'master' of github.com:freescout-helpdesk/freescout into dist 2023-09-08 04:37:02 -07:00
FreeScout
d4f3cd4e6c v1.8.96 2023-09-08 04:36:27 -07:00
FreeScout
0c5a50c34e Remove trailing slash from host name when generating URLs 2023-09-08 01:28:51 -07:00
Philipp Kraft
dfab29bbbc Aria markup for thread options, addendum to #1150
Screen readers do not find the thread-options dropdown, because correct aria markup is missing. Added role, aria-haspopup, and aria-expanded attributes to the dropdown toggle caret
2023-09-08 09:36:57 +02:00
FreeScout
4bbbab7fa1 Automatically check invalid or missing modules symlinks on Modules and System Status pages 2023-09-07 00:12:34 -07:00
FreeScout
4c0b5d1d58 Automatically check invalid or missing modules symlinks on Modules and System Status pages 2023-09-06 23:38:00 -07:00
FreeScout
9f99e784f4 Move star mark when merging conversations - closes #3351 2023-09-06 03:28:55 -07:00
FreeScout
8c673d5242 Do not insert new line in the editor when pasting content - closes #3319 2023-09-05 23:27:01 -07:00
FreeScout
6852d7e14d Update Spanish translation #3343 from Pablohn26/patch-3
Update Spanish translation
2023-09-05 17:31:34 +03:00
FreeScout
204808032e Show SMTP 5xx errors immediately in the conversation - closes #3339 2023-09-05 07:30:19 -07:00
Pablo Hinojosa
8952cdb813 Update es.json
Improve Spanish translation. 
* Adding `¿` and `¡` marks
* Fixing some words without accent mark
2023-09-05 16:17:30 +02:00
FreeScout
bab3eb1e9f Show SMTP Queue ID in Outgoing Emails for sent emails - closes #3330 2023-09-05 04:44:34 -07:00
FreeScout
900bdfb199 Cancel SendReplyToCustomer background jobs when undoing replies - closes #3300 2023-09-05 00:33:52 -07:00
FreeScout
097f404d94 Fix Allow to reply from aliases option being reset when mailbox settings saved by non-admin - closes #3337 2023-09-04 23:30:50 -07:00
FreeScout
f796523e3b Set CURLOPT_SSL_VERIFYPEER option to false for curl and Guzzle requests - closes #3293 2023-09-04 23:24:51 -07:00
FreeScout
44477d7b1a Check symlink function on Status page - closes #3335 2023-09-03 23:49:38 -07:00
FreeScout
f3592d1d60 Fix errors on Status page - closes #3334 2023-09-03 23:35:29 -07:00
FreeScout
b935e20d63 Fix errors on Status page - closes #3334 2023-09-03 23:34:34 -07:00
FreeScout
0e4c8415a1 CustomerChannel::getChannels() function 2023-09-03 08:31:02 -07:00
FreeScout
b342f14bf9 Show DB info and missing migrations on Status page - closes #3326 2023-09-03 03:54:07 -07:00
FreeScout
b8489059f3 Show link to conversation and logs in SendReplyToCustomer jobs on System page - closes #3331 2023-09-03 00:45:01 -07:00
FreeScout
ebfd86bcb9 Show link to conversation and logs in SendReplyToCustomer jobs on System page - closes #3331 2023-09-03 00:39:29 -07:00
FreeScout
1e37ca57bc Store for the future an attempt to get SMTP Queue ID - closes #3330 2023-09-02 23:22:36 -07:00
FreeScout
eabd501dee Update readme 2023-09-02 00:04:35 -07:00
FreeScout
252de7a589 Fix variable name in saveUserThread() on fetching - closes #3325 2023-09-01 06:53:22 -07:00
FreeScout
9be2c1df5a Merge branch 'master' of github.com:freescout-helpdesk/freescout into dist 2023-09-01 03:11:57 -07:00
FreeScout
a35c78d796 v1.8.95 2023-09-01 03:11:03 -07:00
FreeScout
43a8a759af Add GET page parameter when navigating over conversations - closes #3323 2023-09-01 00:50:37 -07:00
FreeScout
92abebaffa Show correct 12 or 24 hour format in date pickers - closes #3322 2023-08-31 23:53:57 -07:00
FreeScout
3b9b149555 Fix Invalid text representation error on PostgreSQL when saving mailbox permissions - closes #3315 2023-08-30 00:29:27 -07:00
FreeScout
8b3433b4ca Improve mail subject decoding - closes #3312 2023-08-28 23:29:54 -07:00
FreeScout
b02e034621 Fix migration creating customer_channel table - closes #3309 2023-08-28 22:48:59 -07:00
FreeScout
196e484448 Add Mail Date and Time option allowing to use date from mail headers when fetching emails - closes #3297 2023-08-28 00:15:59 -07:00
FreeScout
0cd3952d52 Repalce with empty string non-replaced vars in mailbox custom from name - closes #1031 2023-08-27 07:33:48 -07:00
FreeScout
3640508db9 Fix summernote adding new lines when pasting HTML - closes #3264 2023-08-26 09:17:00 -07:00
FreeScout
e75dcaf282 Merge branch 'master' of github.com:freescout-helpdesk/freescout into dist 2023-08-25 21:58:56 -07:00
FreeScout
a7b6b94612 v1.8.94 2023-08-25 21:58:19 -07:00
FreeScout
6ea0ea4619 Remove old records from notifications table - closes #3294 2023-08-23 10:44:58 -07:00
FreeScout
0c71e9cf5f Fix module translation file never imported under certain condition #3289 from totake0224/master
Fix module translation file never imported under certain condition
2023-08-22 09:48:03 +03:00
totake0224
348fbb237b set $locale before preg_match.because if former foreach ended continue condition. module translation file would be never importerd. 2023-08-22 15:35:15 +09:00
FreeScout
e2808ced1a Add exclude_channel parameter to customer->findCustomersBySocialProfile() 2023-08-21 06:11:52 -07:00
FreeScout
30b481597b Merge branch 'master' of github.com:freescout-helpdesk/freescout into dist 2023-08-20 23:29:39 -07:00
FreeScout
c31685b062 v1.8.93 2023-08-20 23:29:29 -07:00
FreeScout
8dbe489d60 Fix Unassigned and Assigned folders - closes #3287 2023-08-20 23:28:42 -07:00
FreeScout
b11ffe9afa Merge branch 'master' of github.com:freescout-helpdesk/freescout into dist 2023-08-20 22:33:03 -07:00
FreeScout
789da461f9 v1.8.92 2023-08-20 22:32:30 -07:00
FreeScout
fb3d1752dc Add an option allowing to restrict users to see only tickets assigned to themselves - closes #701 2023-08-20 03:29:46 -07:00
FreeScout
5219afb13f Add Chinese Simplified language 2023-08-20 00:59:58 -07:00
FreeScout
71e0888c65 Customer findCustomersBySocialProfile() function 2023-08-20 00:03:47 -07:00
FreeScout
e5456c8ca3 Functions for working with customer_channel table 2023-08-19 23:08:03 -07:00
FreeScout
9987ba2fbb In the chat conversation reply area show all buttons after codeview 2023-08-19 23:06:15 -07:00
FreeScout
8ea51c3e41 Update Danish translation 2023-08-19 09:38:24 -07:00
FreeScout
fbd934d750 Store customer to channel mapping in customer_channel table 2023-08-19 08:15:47 -07:00
FreeScout
63d06ee32a Show an error message to support agent if an emial has not been sent after 1 hour - closes #3268 2023-08-18 23:52:54 -07:00
FreeScout
561f1deb07 Add vendor files to dist 2023-08-18 00:04:44 -07:00
FreeScout
584d84475a Merge branch 'master' of github.com:freescout-helpdesk/freescout into dist 2023-08-18 00:02:31 -07:00
FreeScout
c9e56723fb v1.8.91 2023-08-18 00:01:48 -07:00
FreeScout
b5b6e42c2d Allow to send by email to the customer threads in a phone conversation - closes #3270 2023-08-17 01:26:11 -07:00
FreeScout
14e56cd04f Fix Passing null to parameter in HTMLPurifier/Lexer.php - closes #3277 2023-08-16 22:34:47 -07:00
FreeScout
ecfbdd29a7 Speed up Eventy event firing 2023-08-14 23:30:37 -07:00
FreeScout
321a87c407 Speed up Eventy event firing #3263 from OttoWinter/optimize-eventy
Speed up Eventy event firing
2023-08-15 09:14:11 +03:00
Otto Winter
4403fa2238 Add missed change 2023-08-14 21:55:40 +02:00
Otto Winter
f2623f0253 Optimize eventy 2023-08-14 20:58:42 +02:00
FreeScout
36f16d9f9b Fix routes var in ModuleLaroute.php 2023-08-14 06:01:02 -07:00
FreeScout
097d5e3f98 Condense reply toolbar 2023-08-14 01:47:30 -07:00
FreeScout
87267638f7 Update Czech translation 2023-08-13 06:22:31 -07:00
FreeScout
6bcc9b0cc5 Update Polish translation 2023-08-13 03:37:42 -07:00
FreeScout
40fc845461 Merge branch 'master' of github.com:freescout-helpdesk/freescout into dist 2023-08-11 22:03:54 -07:00
FreeScout
18017c73ce v1.8.90 2023-08-11 22:03:21 -07:00
FreeScout
9e69ae6ec0 Allow to use vars in mailbox Custom From Name - closes #1031 2023-08-11 07:28:43 -07:00
FreeScout
0cb4bbcfe2 Improve subject and attachment name decoding - closes #3248 2023-08-08 22:20:00 -07:00
FreeScout
6a2f5657a5 Add app.curl_user_agent parameter 2023-08-06 03:25:30 -07:00
FreeScout
624d84be41 Merge branch 'master' of github.com:freescout-helpdesk/freescout into dist 2023-08-05 23:10:33 -07:00
FreeScout
8045da1f96 v1.8.89 2023-08-05 23:10:05 -07:00
FreeScout
482f428a17 Fix preg_match() Passing null to parameter in Helper.php - closes #3239 2023-08-05 23:08:59 -07:00
FreeScout
663908d17e Merge branch 'master' of github.com:freescout-helpdesk/freescout into dist 2023-08-05 11:07:03 -07:00
FreeScout
3c61ff6895 v1.8.88 2023-08-05 11:06:26 -07:00
FreeScout
be504fc15c Fix shell_exec() error on Status page - closes #3239 2023-08-05 11:04:58 -07:00
FreeScout
60c2bd4808 Take into account not only created_at but also thread ID when sorting threads - closes #3240 2023-08-05 04:05:16 -07:00
FreeScout
03c584a5c3 Fix an issue with the customer reply connected to the wrong conversation - closes #3231 2023-08-04 06:47:25 -07:00
FreeScout
3570c48420 Merge branch 'master' of github.com:freescout-helpdesk/freescout into dist 2023-08-03 23:22:23 -07:00
FreeScout
aac5df9748 v1.8.87 2023-08-03 23:21:49 -07:00
FreeScout
884fa08355 Save .ICS attachments having no name as calendar.ics - closes #1412 2023-07-31 22:08:37 -07:00
FreeScout
59dbc520b9 Update Italian translation 2023-07-31 21:46:18 -07:00
FreeScout
8075bf14ec Save CC and BCC when saving outgoing email to the Sent IMAP folder - closes #3228 2023-07-31 04:26:16 -07:00
FreeScout
8e0d993596 Save CC and BCC when saving outgoing email to the Sent IMAP folder - closes #3228 2023-07-31 04:23:53 -07:00
FreeScout
6c87713751 Improve subject decoding - closes #3196 2023-07-18 06:55:38 -07:00
FreeScout
43ecd35402 Improve subject decoding 2023-07-18 06:39:49 -07:00
FreeScout
424c89e2c8 Allow to view .json, .diff and .patch attachments - closes #3192 2023-07-17 23:12:12 -07:00
FreeScout
744ccef561 Check pcntl extension in the console version of PHP on Status page - closes #3190 2023-07-17 22:48:18 -07:00
FreeScout
7f877ee636 Make sure that conversation subject has String type when fetching emails 2023-07-17 10:31:37 -07:00
FreeScout
542d6dc061 Remove FUNDING.yml 2023-07-17 09:56:43 -07:00
FreeScout
bd1bdc03c2 Make sure that conversation subject has String type when fetching emails 2023-07-17 06:22:12 -07:00
FreeScout
b0be55ef2e Update Readme 2023-07-17 03:09:16 -07:00
FreeScout
6f332d8c2d Update readme 2023-07-17 03:06:05 -07:00
FreeScout
cf2f488aaf Merge branch 'master' of github.com:freescout-helpdesk/freescout into dist 2023-07-17 01:40:15 -07:00
FreeScout
8c91df4319 v1.8.86 2023-07-17 01:39:12 -07:00
FreeScout
807eba8d98 Do not delete the message when another user discards a draft of the reply which just has been sent - closes #2873 2023-07-17 01:04:22 -07:00
FreeScout
71fb3b1313 Allow to set trusted proxies via .env file APP_TRUSTED_PROXIES parameter - closes #1994 2023-07-17 00:12:00 -07:00
FreeScout
2b9f56b456 Helper::getClientIp() function 2023-07-15 23:20:47 -07:00
FreeScout
9266e5c207 Allow to show custom message on 403 error page 2023-07-15 23:02:56 -07:00
FreeScout
ffe2adc4c2 Login hooks 2023-07-15 06:11:45 -07:00
FreeScout
9b6fa32db5 Fix References header in emails to customers - closes #3175 2023-07-14 10:24:07 -07:00
FreeScout
fdea5e302f Merge branch 'master' of github.com:freescout-helpdesk/freescout into dist 2023-07-14 06:40:55 -07:00
FreeScout
4fbd276fff v1.8.85 2023-07-14 06:40:19 -07:00
FreeScout
90536704a3 Improve iso-2022-jp subjects and attachment names decoding - closes #3185 2023-07-14 04:28:10 -07:00
FreeScout
f8787c67df Update \MailHelper::decodeSubject() 2023-07-14 03:27:06 -07:00
FreeScout
2cea3a6585 Do not create empty conversation when same email is being fetched at the same time - #3186 2023-07-14 03:25:08 -07:00
FreeScout
61edffd0b6 Fix Attempt to read property id on null in reply_fancy - closes #3182 2023-07-13 22:57:42 -07:00
FreeScout
6494ca8c26 List all Message-IDs in References header in replies to customers - closes #3175 2023-07-12 11:05:30 -07:00
FreeScout
480448ff79 Improve suject decoding - closes #3177 2023-07-12 07:18:34 -07:00
FreeScout
8139f91db2 Update Russian translation 2023-07-12 01:21:42 -07:00
FreeScout
3d7f424b28 Limit the number of displayed non writable cache files on Status page - closes #3165 2023-07-09 22:48:33 -07:00
FreeScout
9e514447e6 Merge pull request #3172 from sulemaanhamza/master
Fixed undefined variable bug in the FollowerObserver
2023-07-08 12:15:22 +03:00
suleman
06ed4c8da7 Fixed undefined variable bug in FollowerObserver 2023-07-08 13:47:59 +05:00
FreeScout
072c3f8be9 Add vendor files to dist 2023-07-07 00:28:42 -07:00
FreeScout
37b158e99b Merge branch 'master' of github.com:freescout-helpdesk/freescout into dist 2023-07-07 00:26:34 -07:00
FreeScout
a327c0b321 v1.8.84 2023-07-07 00:25:55 -07:00
FreeScout
d57dc285df Improve subject decoding - closes #3167 2023-07-06 23:45:46 -07:00
FreeScout
e29cfc7b88 Do not encode HTML entities in outoging plain text emails - closes #3159 2023-07-06 02:56:11 -07:00
FreeScout
08c7a4033e Update German translation 2023-07-06 02:36:32 -07:00
FreeScout
b9dd2b7cbc Fix GuzzleHttp\Psr7\Uri::withScheme() error on PHP 7.1 - closes #3158 2023-07-05 00:20:32 -07:00
FreeScout
e45eccd64c Do not try to resend email notifications on received bounce emails - closes #3156 2023-07-04 23:25:57 -07:00
FreeScout
c93411e330 Update message shown when no activations left for the license key 2023-07-04 23:18:55 -07:00
FreeScout
550e2d30cc Fix PHP version check in tools.php - closes #3162 2023-07-04 22:50:19 -07:00
FreeScout
48e4cfadfd Check pcntl extension status in System to avoid Undefined constant SIGKILL error 2023-07-04 00:57:25 -07:00
FreeScout
c43e41c076 Merge branch 'master' of github.com:freescout-helpdesk/freescout into dist 2023-06-30 20:37:11 -07:00
FreeScout
45af81513c v1.8.83 2023-06-30 20:36:24 -07:00
FreeScout
5244b5c8f0 Fix retrieveing attachments - closes #3154 2023-06-30 20:35:10 -07:00
FreeScout
ff36b2fef1 Add vendor files to dist 2023-06-30 00:40:52 -07:00
FreeScout
b27997db2c Merge branch 'master' of github.com:freescout-helpdesk/freescout into dist 2023-06-30 00:39:35 -07:00
FreeScout
b0b9a621a1 v1.8.82 2023-06-30 00:38:47 -07:00
FreeScout
f851e70d28 Make using imap_utf8_to_mutf7() function optional in Webklex/laravel-imap library - closes #3152 2023-06-30 00:36:05 -07:00
FreeScout
09a5d1520d email.reply_to_customer.threads hook 2023-06-29 00:48:39 -07:00
FreeScout
7ba097e34c Update NL translation 2023-06-28 23:07:47 -07:00
FreeScout
2141e1f4da Preserve new lines when replacing vars in the signature - closes #3146 2023-06-28 07:20:12 -07:00
FreeScout
9c0fd7b027 Preserve new lines when replacing vars in the signature - closes #3146 2023-06-28 07:10:14 -07:00
FreeScout
fa9289293b Improve subject decoding 2023-06-27 23:36:16 -07:00
FreeScout
3092424315 Fixed saving data into Timestamp field on PostgreSQL 2023-06-27 01:14:05 -07:00
FreeScout
2abe327e90 Fix Undefined property: Webklex\IMAP\Attachment::config - closes #3142 2023-06-26 23:24:11 -07:00
FreeScout
47ebc2f694 Improve decoding strings in Webklex/laravel-imap library 2023-06-26 11:33:57 -07:00
FreeScout
9312036f69 Improve decoding strings in Webklex/laravel-imap library 2023-06-26 07:10:19 -07:00
FreeScout
5732b8456f Update readme 2023-06-25 06:07:21 -07:00
FreeScout
7fd01b7e40 Show proper error when module license key is invalid 2023-06-23 22:21:12 -07:00
FreeScout
fc72dfc870 Show proper error when module license key is invalid 2023-06-23 12:10:04 -07:00
FreeScout
24dc14c44a Add vendor files to dist 2023-06-22 00:14:37 -07:00
FreeScout
1e291d4180 Merge branch 'master' of github.com:freescout-helpdesk/freescout into dist 2023-06-22 00:11:31 -07:00
FreeScout
1af3310e0b v1.8.81 2023-06-22 00:10:52 -07:00
FreeScout
e90c1838f1 Change iso-2022-jp encoding to iso-2022-jp-ms when decoding data in Webklex/php-imap library - closes #3122 2023-06-22 00:05:10 -07:00
FreeScout
88932bfc67 Fix decoding sender name in iso-2022-jp encoding - closes #3089 2023-06-19 06:47:56 -07:00
FreeScout
17205d39d2 Improve decoding attachment names with Webklex/PHP-IMAP library - closes #2753 2023-06-19 06:25:08 -07:00
FreeScout
9512104536 Improve decoding attachment names with Webklex/PHP-IMAP library - closes #2753 2023-06-19 05:06:47 -07:00
FreeScout
4eabdc489f Improve body encoding conversion on fetchign - closes #3089 2023-06-19 02:13:21 -07:00
FreeScout
fd9865b368 Revert formatEmailList() update - closes #3118 2023-06-19 01:49:45 -07:00
FreeScout
c5a8dca36f Prevent Attempt to read property mail on fetching - closes #3118 2023-06-19 00:33:40 -07:00
FreeScout
49d0a2aaf0 Improve subject decoding - closes #3089 2023-06-15 05:40:47 -07:00
FreeScout
b5b941bf73 Do not use @unknown email from Reply-To on fetching - closes #3101 2023-06-14 22:34:15 -07:00
FreeScout
6cb39bd6ee Improve email validation: do not allow @unknown emails - closes #3101 2023-06-13 23:18:26 -07:00
FreeScout
b6b1292589 Merge branch 'master' of github.com:freescout-helpdesk/freescout into dist 2023-06-05 10:32:38 -07:00
FreeScout
2d4e4e71ab v1.8.80 2023-06-05 10:32:08 -07:00
FreeScout
8194d416c6 Fix an issue with HTTPS redirect - closes #3075, #3070 2023-06-05 10:30:13 -07:00
FreeScout
d3aa94a922 Merge branch 'master' of github.com:freescout-helpdesk/freescout into dist 2023-06-03 02:33:01 -07:00
FreeScout
0d0ca9a73a v1.8.79 2023-06-03 02:32:27 -07:00
FreeScout
f096e93a09 Fix error on Users page when user first name is empty - closes #2972 2023-06-02 03:06:45 -07:00
FreeScout
678c9b029b Improve subject decoding with iconv_mime_decode() - closes #3066 2023-06-01 02:28:45 -07:00
FreeScout
98d5986dde Fix module activation issue when /public/modules symlink exists but leads to wrong path 2023-06-01 00:42:49 -07:00
FreeScout
56f00fe6a6 Fix module activation issue when /public/modules symlink exists but leads to wrong path 2023-06-01 00:04:56 -07:00
FreeScout
3214bbc427 Do not try to send email again if mail server replies: message file too big - closes #3065 2023-05-31 23:44:24 -07:00
FreeScout
6e52046032 Decode subjects using iconv_mime_decode() in Webklex/php-imap library - closes #3039 2023-05-31 02:00:21 -07:00
FreeScout
9d4c43f96d Fix Undefined array key 0 error in Subscription class - closes #3059 2023-05-31 00:01:11 -07:00
FreeScout
0ef404f3ef Replace base64 images in messages with attachment URLs - closes #3057 2023-05-30 23:53:20 -07:00
FreeScout
ac76251b75 Update German translation 2023-05-30 07:29:53 -07:00
FreeScout
c97610bd97 Show translated filter names in the Search - closes #3058 2023-05-30 07:29:05 -07:00
FreeScout
722349f586 Fix subject with colon being truncated with Webklex/php-imap library - closes #2964 2023-05-30 00:36:26 -07:00
FreeScout
5aabac7b4f Remove app.force_https parameter and determine protocol from app.url parameter - closes #3053 2023-05-28 00:35:51 -07:00
FreeScout
ee2269fdf1 Add vendor files to dist 2023-05-28 00:09:31 -07:00
FreeScout
adb1e309e3 Merge branch 'master' of github.com:freescout-helpdesk/freescout into dist 2023-05-28 00:07:57 -07:00
FreeScout
a5f77e7846 v1.8.78 2023-05-28 00:07:36 -07:00
FreeScout
4711ea8c7f Update German translation 2023-05-27 06:59:47 -07:00
FreeScout
769529e129 Fix saving OpenOffice attachments - closes #3048 2023-05-24 23:07:09 -07:00
FreeScout
5b0f1f974c Show links hrefs only in thread content in the printed version - closes #3045 2023-05-23 22:53:58 -07:00
FreeScout
cf22374926 Allow to specify unlimited number of recipients in new conversation draft - closes #3036 2023-05-22 07:28:46 -07:00
FreeScout
56a52c6237 Do not show attachment URLs in printed version - closes #3035 2023-05-22 00:42:34 -07:00
FreeScout
04fd44f8c2 Set customer First and Last Name max length to 255 symbols - closes #3033 2023-05-22 00:32:13 -07:00
FreeScout
a43729e9c1 Allow to set same_site to none in config/session.php - closes #3023 2023-05-17 23:32:29 -07:00
FreeScout
84314598d2 Merge branch 'master' of github.com:freescout-helpdesk/freescout into dist 2023-05-14 10:13:00 -07:00
FreeScout
9991c368cf v1.8.77 2023-05-14 10:12:29 -07:00
FreeScout
2dfe5e6b64 Fix minutes formatting in 12-hour clock mode - closes #2997 2023-05-14 10:09:52 -07:00
FreeScout
57b67838f8 Add customer.deleting hook #3003 from Lars-/master
Add customer.deleting hook
2023-05-11 11:15:59 +03:00
Lars Jansen
f4f49735be feat: add customer deleting event
This commit adds a new method to the CustomerObserver class that triggers an event when a customer is being deleted.
2023-05-11 10:10:20 +02:00
FreeScout
1a76549c2e Properly thread into conversations replies from Jira - #2927 2023-05-10 23:37:50 -07:00
FreeScout
02a1f4a89c Merge pull request #3001 from avenjamin/master
Unfollow followed conversation when re/assigned
2023-05-11 09:23:16 +03:00
Avenjamin
cc7e6aa9ec unfollow followed conversation when re/assigned
If a user is "following" a conversation and the conversation is then assigned to them they no longer need to follow it.
2023-05-11 09:41:52 +10:00
FreeScout
b78838ca23 Fix updating custom folders counters - closes #2998 2023-05-10 03:21:40 -07:00
FreeScout
a54b6a4195 Add vendor files to dist 2023-05-09 22:29:56 -07:00
FreeScout
14e03bf903 Merge branch 'master' of github.com:freescout-helpdesk/freescout into dist 2023-05-09 22:27:17 -07:00
FreeScout
dc8f2c53c9 v1.8.76 2023-05-09 22:26:15 -07:00
FreeScout
fe1563fb03 Fix Passing null error in emails template - closes #2989 2023-05-09 06:47:06 -07:00
FreeScout
82628607d6 Allow to reply from alises option for mailboxes - closes #2988 2023-05-09 06:43:30 -07:00
FreeScout
1a9b178f67 Fix showing mailbox mute status for non-admin users - closes #2992 2023-05-09 06:22:43 -07:00
FreeScout
db4f8ed299 Add PHP and FreeScout versions to General Help Request template 2023-05-07 23:32:25 -07:00
FreeScout
0318f3f785 Limit Insert variable dropdown width to avoid issues in Firefox - closes #2966 2023-05-07 23:28:39 -07:00
FreeScout
60914553c3 Improve subject decoding - closes #2987 2023-05-07 23:18:57 -07:00
FreeScout
939c2c52fa Improve sanitizing SVG files 2023-05-06 09:02:18 -07:00
FreeScout
f8aba65578 Improve sanitizing SVG files 2023-05-06 07:07:44 -07:00
FreeScout
8fc1f7668b Improve displaying tables in conversations - closes #2969 2023-05-06 04:52:30 -07:00
FreeScout
18ad759d43 Improve background to background-color conversion - closes #2969 2023-05-06 01:14:35 -07:00
FreeScout
550ca6f7dd Merge branch 'master' of github.com:freescout-helpdesk/freescout into dist 2023-05-05 21:57:58 -07:00
FreeScout
e81829a203 v1.8.75 2023-05-05 21:57:25 -07:00
FreeScout
257dfb8474 Allow to update folders counters in background 2023-05-05 07:06:17 -07:00
FreeScout
6a8be9661d Allow to update folders counters in background #2982 from Lars-/master
Allow to update folders counters in background
2023-05-05 16:47:49 +03:00
Lars Jansen
b51bffa173 fix: performance gain by updating folder counters in a job 2023-05-05 15:03:29 +02:00
FreeScout
56db1b8023 Take into account mailbox From Name settings when sending a reply to customer from mailbox alias - closes #2976 2023-05-04 23:18:49 -07:00
FreeScout
6c949b18af Fix an issue with a note being created instead of reply in phone conversation - closes #2953 2023-05-04 22:52:41 -07:00
FreeScout
b776827cfb Remove default SMTP host and port from config - closes #2978 2023-05-04 21:42:53 -07:00
FreeScout
951d0f322b Use iconv_mime_decode() instead of imap_utf8() for UTF-8 encoded subjects - #2965 2023-05-03 23:00:03 -07:00
FreeScout
1288670a72 Automatically load new notes when viewing a conversation - closes #2961 2023-05-02 22:50:47 -07:00
FreeScout
1398f02865 Restart swiftmailer after each email sent to remove temp files - closes #2949 2023-05-02 05:48:48 -07:00
FreeScout
3c3f25adce Fix seconds format in translated dates 2023-05-02 01:45:00 -07:00
FreeScout
2fe0f518be Merge branch 'master' of github.com:freescout-helpdesk/freescout into dist 2023-05-02 01:35:30 -07:00
FreeScout
a67f35e659 v1.8.74 2023-05-02 01:34:59 -07:00
FreeScout
e071abda6e Show dates translated into selected language - closes #2950 2023-05-02 01:34:15 -07:00
FreeScout
37421bd258 Show dates translated into selected language - closes #2950 2023-05-01 23:26:06 -07:00
FreeScout
f2f9ac533d Do not show From (Alias) field when creating a phone conversation 2023-04-27 22:14:45 -07:00
FreeScout
02a58f07a5 Show dates translated into selected language - closes #2950 2023-04-26 22:18:28 -07:00
FreeScout
34eb6bf84c Show dates translated into selected language - closes #2950 2023-04-26 22:06:56 -07:00
FreeScout
7e49207ad9 Show dates translated into selected language - closes #2950 2023-04-26 10:51:44 -07:00
FreeScout
2f21645b39 Show dates translated into selected language - closes #2950 2023-04-26 06:44:21 -07:00
FreeScout
3572c95448 Show dates translated into selected language - closes #2950 2023-04-26 05:30:57 -07:00
FreeScout
3892d12a1f Fix wrong messages order in the email to customer in some cases - closes #2938 2023-04-25 23:20:55 -07:00
FreeScout
9973837e63 Clean temp files daily instead of weekly - closes #2949 2023-04-25 22:43:14 -07:00
FreeScout
e896a79dac Allow to select mailbox alias in From field when creating a new conversation - closes #656 2023-04-24 23:17:45 -07:00
FreeScout
309b832f6c Merge branch 'master' of github.com:freescout-helpdesk/freescout into dist 2023-04-23 07:52:10 -07:00
FreeScout
eca72d744e v1.8.73 2023-04-23 07:51:10 -07:00
FreeScout
e63ea84226 Fix replying to email notifications by users - closes #2941 2023-04-23 07:49:32 -07:00
FreeScout
c8322ada6f Updaet Czech translation 2023-04-21 22:12:46 -07:00
FreeScout
67e73fcbc3 Add vendor files to dist 2023-04-20 22:52:00 -07:00
FreeScout
e2f51b074e Merge branch 'master' of github.com:freescout-helpdesk/freescout into dist 2023-04-20 22:50:44 -07:00
FreeScout
10b8ae0e74 v1.8.72 2023-04-20 22:50:13 -07:00
FreeScout
a484cf8236 If Email notifications are disabled use Browser notifications settings to show Bell notifications in the top menu - closes #1074 2023-04-19 23:51:27 -07:00
FreeScout
a94f97e5a2 Improve @fwd email detection - closes #2929 2023-04-19 22:56:49 -07:00
FreeScout
ca48719464 Sanitize mailbox email when creating or updating the mailbox - closes #9154 2023-04-18 22:19:58 -07:00
FreeScout
adc3b832b8 Add Norwegian translation 2023-04-18 01:30:33 -07:00
FreeScout
ec89f0e57d Sanitize mailbox email when creating or updating the mailbox - closes #9154 2023-04-18 00:51:31 -07:00
FreeScout
65060592b4 Allow to reply from Mailbox Aliases - closes #656 2023-04-17 07:30:52 -07:00
FreeScout
c329dd5f20 Allow to change user photo size via APP_USER_PHOTO_SIZE .env file variable 2023-04-15 00:33:33 -07:00
FreeScout
59f918f099 Allow to change customer photo size via APP_CUSTOMER_PHOTO_SIZE .env variable - closes #2919 2023-04-15 00:22:23 -07:00
FreeScout
f818134c2d Use proxy setting from .env when checking and downloading new release - closes #2911 2023-04-14 01:00:55 -07:00
FreeScout
a3fa817a37 Merge branch 'master' of github.com:freescout-helpdesk/freescout into dist 2023-04-12 06:23:47 -07:00
FreeScout
24201fa0fb v1.8.71 2023-04-12 06:23:14 -07:00
FreeScout
aba3421a1d Pass threads_count to reply_email.before_signature and reply_email.after_signature hooks - closes #2908 2023-04-11 06:28:09 -07:00
FreeScout
ead9233560 Update Polish translation 2023-04-10 22:51:33 -07:00
FreeScout
3a09c344e5 Update Italian translation 2023-04-09 01:45:35 -07:00
FreeScout
51174a75bb Improve PHP version check in tools.php - closes #2901 2023-04-06 02:42:03 -07:00
FreeScout
0715e452fc Update pt-BR translation 2023-04-05 07:09:19 -07:00
FreeScout
6fdb19a86a Rename menu hook into menu.mailbox_single.after_name 2023-04-05 07:08:15 -07:00
FreeScout
71301ad1fe Add vendor files to dist 2023-04-04 03:07:24 -07:00
FreeScout
ae67a1375c Merge branch 'master' of github.com:freescout-helpdesk/freescout into dist 2023-04-04 03:03:03 -07:00
FreeScout
b30b48f16d v1.8.70 2023-04-04 02:59:48 -07:00
FreeScout
cc0f86ab53 Escape link text in the editor 2023-04-04 02:49:27 -07:00
FreeScout
6b1b061b26 Take into account proxy settings from .env in Helper::getRemoteFileContents() 2023-04-03 22:55:51 -07:00
FreeScout
87e427ccf4 Add Norwegian language 2023-04-01 06:54:53 -07:00
FreeScout
35d29eb216 Change freescout:send-monitor description - closes #2881 2023-04-01 06:27:19 -07:00
FreeScout
b2bc4cabce Update Russian translation 2023-04-01 05:44:15 -07:00
FreeScout
c8f5198c06 Fix selecting conversations via long press in mobile app - closes #2868 2023-04-01 03:14:12 -07:00
FreeScout
fb4ab34e2a Change freescout:send-monitor description - closes #2881 2023-04-01 02:56:49 -07:00
FreeScout
6c24b618bb Retry background job button - closes #2881 2023-04-01 02:53:28 -07:00
FreeScout
c0904f07e9 Change queue:work check interval - closes #2876 2023-04-01 02:47:23 -07:00
FreeScout
90f1c0a737 Retry background job button - closes #2881 2023-04-01 02:38:30 -07:00
FreeScout
00893a00a4 Open links in another tab 2023-03-31 00:01:18 -07:00
FreeScout
df54432000 Improve Filesystem.php security on Windows 2023-03-30 23:35:14 -07:00
FreeScout
0d1a05edbb Revert conversation preview after undoing sending a reply - closes #2874 2023-03-30 23:18:26 -07:00
FreeScout
b5f93ed153 Update readme 2023-03-30 22:25:04 -07:00
FreeScout
7aa8617ff6 Remove SMTP mail service providers info from mailbox Sending Emails page - #2862 2023-03-30 22:19:53 -07:00
FreeScout
3144fbf7b2 Format dates in search 2023-03-22 11:22:24 -07:00
FreeScout
15787aaa0f Helper::sqlLikeOperator() function 2023-03-19 22:20:11 -07:00
FreeScout
5999ac2944 Fix typo in check-requirements command 2023-03-19 22:19:33 -07:00
FreeScout
788a793292 Merge branch 'master' of github.com:freescout-helpdesk/freescout into dist 2023-03-17 22:01:57 -07:00
FreeScout
4036bb6de3 v1.8.69 2023-03-17 22:01:26 -07:00
FreeScout
c9c698da03 Revert the change in Reply-To header processing on fetching - closes #2833 2023-03-17 21:58:38 -07:00
FreeScout
a76c512a1e Fix empty body issue when fetching emails via Webklex/php-imap library - closes #1972 2023-03-17 07:21:49 -07:00
FreeScout
867876c1b7 Fix in Docker mode checking queue:work status on Status page and killing background processes that stuck 2023-03-17 05:15:18 -07:00
FreeScout
8f809a53d9 Merge branch 'master' of github.com:freescout-helpdesk/freescout into dist 2023-03-16 23:53:32 -07:00
FreeScout
f93154cbb4 v1.8.68 2023-03-16 23:51:12 -07:00
FreeScout
a454ded9d2 Merge branch 'master' of github.com:freescout-helpdesk/freescout 2023-03-16 23:49:20 -07:00
FreeScout
478aa72f0c Update conversation preview when deleting a note - closes #2832 2023-03-16 23:46:14 -07:00
FreeScout
8b8e49f552 Fix popover z-index - closes #2829 2023-03-16 05:31:30 -07:00
FreeScout
3eb0e9213c Add menu.mailbox.before_name and after_name actions for only one mailbox #2827 from avenjamin/master
Add menu.mailbox.before_name and after_name actions for only one mailbox
2023-03-16 09:33:56 +03:00
FreeScout
b4e6089f61 Allow single backslashes in .env file - closes #2822 2023-03-15 23:31:15 -07:00
FreeScout
924473b254 Do not use Reply-To as a sender email for auto-responders - closes #2826 2023-03-15 23:14:48 -07:00
FreeScout
29177f5c1c Accept forwarded emails with just Fwd: subject 2023-03-15 11:17:42 -07:00
Avenjamin
309b355d41 Add menu.mailbox.before_name and after_name actions when only one mailbox
If there's only one mailbox the existing before_name and after_name action's didn't apply.
2023-03-16 00:27:52 +11:00
FreeScout
fd05a47156 Substitute customer in the worwarded email only if there is @fwd in the email - closes #2813 2023-03-14 23:52:11 -07:00
FreeScout
dc685bbafb Create vendor/natxet/cssmin/src folder in composer.json for Docker - closes #2583 2023-03-14 22:49:08 -07:00
FreeScout
5901132900 Allow single backslashes in .env file - closes #2822 2023-03-14 07:42:41 -07:00
FreeScout
f996d024e7 Use curl instead of file_get_contents() to load remote files 2023-03-13 23:19:59 -07:00
FreeScout
33a05b7176 mail.fetch_message.imap_folders hook - closes #2820 2023-03-13 01:33:34 -07:00
FreeScout
929811b154 Add menu.mailbox.after_name hook #2816 from avenjamin/master
Add menu.mailbox.after_name hook
2023-03-10 15:09:36 +03:00
Avenjamin
47eaa65056 Add menu.mailbox.after_name @action
Add @action to allow customisation *after* the mailbox name in the mailbox menu. e.g. add unassigned conversation count.
2023-03-10 22:59:58 +11:00
FreeScout
1bc5f606aa Do not substitute the customer in forwarded by support agent email if the email starts with @fwd - closes #2813 2023-03-10 03:16:21 -08:00
FreeScout
8c214c7d90 Update Czech translation 2023-03-09 21:55:06 -08:00
FreeScout
c1de256ae7 Fix Typos #2812 from avenjamin/master
Fix Typos
2023-03-10 08:53:19 +03:00
Avenjamin
6362f905aa Revert getAssesibleFolders typo
Ignore getAssesibleFolders typo as it's used by various modules
2023-03-09 23:26:30 +11:00
Avenjamin
a3356cb76b Fix Typos
fix various typos
2023-03-09 23:03:46 +11:00
FreeScout
8c0afd34c1 Merge branch 'master' of github.com:freescout-helpdesk/freescout into dist 2023-03-09 00:25:23 -08:00
FreeScout
6252e73127 v1.8.67 2023-03-09 00:24:56 -08:00
FreeScout
3aaed00349 Update Helper::2808() warning message 2023-03-08 23:57:28 -08:00
FreeScout
5b2ff85187 Update Helper::2808() warning message 2023-03-08 23:54:29 -08:00
FreeScout
992c25e8c8 Show an alert in the mailbox to all users if there are problems with emails queue processing - closes #2808 2023-03-08 23:53:16 -08:00
FreeScout
5adb116141 Send alerts to activated admins only 2023-03-08 06:05:17 -08:00
FreeScout
05c76c6584 Detect incoming message as a reply when original email sent to multiple mailboxes - closes #2807 2023-03-08 04:33:12 -08:00
FreeScout
863863a7ac .link-active style 2023-03-08 04:32:05 -08:00
FreeScout
b144823cd5 thread.info.prepend 2023-03-08 04:31:45 -08:00
FreeScout
1c968bda9d conversation.view.threads hook 2023-03-08 04:31:33 -08:00
FreeScout
fb6b31106d Clean updater folder before installing a new app version to avoid installing some random release 2023-03-04 00:04:43 -08:00
FreeScout
bde0b18824 Add vendor files to dist 2023-03-03 22:06:52 -08:00
FreeScout
44084b4f1d Merge branch 'master' of github.com:freescout-helpdesk/freescout into dist 2023-03-03 22:05:26 -08:00
FreeScout
29423e03de v1.8.66 2023-03-03 22:04:59 -08:00
FreeScout
4141758ee4 Fix Mailbox name is not valid mUTF-7 error for Webklex/laravel-imap - closes #2793 2023-03-03 05:56:16 -08:00
FreeScout
0f3aeab653 Webklex/php-imap Fix not all attachments are pushed to the collection 2023-02-28 22:44:25 -08:00
FreeScout
a87a37ca54 Webklex/php-imap Prevent the structure parsing from parsing an empty part 2023-02-28 22:40:27 -08:00
FreeScout
cd096eacbf Webklex/php-imap Prevent infinite loop in ImapProtocol 2023-02-28 22:27:23 -08:00
FreeScout
fd40451ef0 Improved retrieving original message with wekblex/php-imap library 2023-02-28 22:15:03 -08:00
FreeScout
0845cd1982 Fix attachment names encoded in windows-1258 in webklex/laravel-imap - closes #2782 2023-02-28 09:44:31 -08:00
FreeScout
133341c379 Update Czech translation 2023-02-28 06:04:14 -08:00
FreeScout
4a27791524 Fix attachment names encoded in windows-1258 in webklex/laravel-imap - closes #2782 2023-02-28 06:03:39 -08:00
FreeScout
3767e0bfd2 Add Finnish language 2023-02-27 23:43:05 -08:00
FreeScout
e0c7370395 Add Finnish language 2023-02-27 23:42:15 -08:00
FreeScout
a4aa6abc9e When deleting an email from customer do not create a new customer if there are no conversations with such email - closes #2767 2023-02-27 23:38:08 -08:00
FreeScout
7b5572f5de Merge branch 'master' of github.com:freescout-helpdesk/freescout into dist 2023-02-26 23:28:39 -08:00
FreeScout
46cb52bd2b v1.8.65 2023-02-26 23:28:14 -08:00
FreeScout
996758f6d1 Merge branch 'master' of github.com:freescout-helpdesk/freescout into dist 2023-02-26 23:24:18 -08:00
FreeScout
4952912e16 v1.8.64 2023-02-26 23:24:03 -08:00
FreeScout
b9366bc3f2 Fix Undefined array key argv error 2023-02-26 23:22:52 -08:00
FreeScout
e21e48626d Optimize queue:work monitoring 2023-02-26 22:54:16 -08:00
FreeScout
313cd61975 Merge branch 'master' of github.com:freescout-helpdesk/freescout into dist 2023-02-26 22:28:05 -08:00
FreeScout
fb71bef6f6 v1.8.63 2023-02-26 22:27:42 -08:00
FreeScout
717ab19c07 Fix creating a new conversation with Send and go to next active option - closes #2769 2023-02-26 22:25:16 -08:00
FreeScout
95bf16da60 Fix undefined variable To on fetching forwarded email - closes #2771 2023-02-26 19:59:42 -08:00
FreeScout
7664faaf44 Kill fetch-emails commands running for too long - closes #2489, #2762 2023-02-26 09:51:05 -08:00
FreeScout
48736ea1d0 Add vendor files to dist 2023-02-25 21:14:43 -08:00
FreeScout
4ace088465 Merge branch 'master' of github.com:freescout-helpdesk/freescout into dist 2023-02-25 21:10:58 -08:00
FreeScout
57b92938fb v1.8.62 2023-02-25 21:10:38 -08:00
FreeScout
09b5605d04 Do not show message ID in the Gmail snippet preview - closes #2752 2023-02-25 03:21:26 -08:00
FreeScout
1d3aaca944 Do not convert phone conversation into email conversation when adding a note - closes #2766 2023-02-24 22:35:28 -08:00
FreeScout
1ecf3ae23d Fixed an issue with email notifications being sent to the user when they should not be sent - closes #2764 2023-02-24 22:15:41 -08:00
FreeScout
924b47635d Create a conversation on behalf of a customer when support agent forwards an email only when it is sent to one address - closes #2761 2023-02-24 21:06:10 -08:00
FreeScout
a62da2c890 Improve detecting customer email when fetching emails forwarded by support agents - closes #2763 2023-02-23 04:31:43 -08:00
FreeScout
0653551d93 Fix incorrect customer email detection when fetching forwarded email - closes #2763 2023-02-22 23:11:47 -08:00
FreeScout
f581f52a6f Do not add convesations count to the title when saving a draft 2023-02-22 22:48:52 -08:00
FreeScout
323ce17ef1 Fix saving outgoing emails to the IMAP folder with new Webklex IMAP library 2023-02-22 22:43:36 -08:00
FreeScout
4abe0200fb Fix retrieving folders list in mailbox Fetching settings with new Webklex IMAP library 2023-02-22 22:17:37 -08:00
FreeScout
fa5c4f906f Rename Fetching Interval option into Fetching Interval 2023-02-22 21:58:42 -08:00
FreeScout
fe63a665d1 Do not add Re: when forwarding - closes #2759 2023-02-22 04:34:46 -08:00
FreeScout
73bac1622a Do not add Re: to the email saved in IMAP folder when creating new conversation or forwarding - closes #2509 2023-02-22 04:11:06 -08:00
FreeScout
0b51653658 Fix undefined attachment names with webklex/php-imap library - closes #2753 2023-02-21 22:41:44 -08:00
FreeScout
94807fd30a layout.favicon hook - closes #2754 2023-02-21 22:13:02 -08:00
FreeScout
074d8d6c13 Take into account proxy settings in Helper::downloadRemoteFile() - closes #2755 2023-02-21 21:25:31 -08:00
FreeScout
59f510dfa9 Set closed_at when creating a conversation and mailbox Status After Replying is Closed - closes #2751 2023-02-21 06:19:15 -08:00
FreeScout
7828e6e284 Fix Send and stay on the page option when creating a new conversation 2023-02-21 06:07:58 -08:00
FreeScout
92ef753708 Update NL translation 2023-02-21 00:56:26 -08:00
FreeScout
62dae9a141 Update NL translation 2023-02-21 00:55:50 -08:00
FreeScout
24c9eb7185 When an attachment can not be saved to the IMAP folder - save an email without attachments - closes #2749 2023-02-21 00:52:53 -08:00
FreeScout
470bb614b9 Fix apple-touch-icon.png on subfolder installation 2023-02-20 00:07:09 -08:00
FreeScout
2a52506a2c Merge branch 'master' of github.com:freescout-helpdesk/freescout into dist 2023-02-19 23:43:35 -08:00
FreeScout
9557f2d06d v1.8.61 2023-02-19 23:43:11 -08:00
FreeScout
947d693a15 Add favicon to the layout - closes #2746 2023-02-19 23:42:08 -08:00
FreeScout
fa58d144b9 Fix manifest and mask-icon path for subfolder installation - closes #2746 2023-02-19 23:22:25 -08:00
FreeScout
136304ce8b Shorten text in the conversations table footer - closes #2743 2023-02-19 06:01:04 -08:00
FreeScout
16f5a6dce1 When user replies to the email notification send reply to CC emails too - closes #2740 2023-02-19 00:41:56 -08:00
FreeScout
ff6d7ce7e4 Fix Logs date format display issue with 12hr date format 2023-02-18 23:24:17 -08:00
FreeScout
1123d22446 When user replies to the email notification send reply to CC emails too - closes #2740 2023-02-18 22:10:45 -08:00
FreeScout
adc39bd9fe Improve attachments mime type detection when attachment is created from remote URL 2023-02-18 03:08:36 -08:00
FreeScout
dea7ec57f3 Do not write a notice to the log when incoming email date can not be parsed - closes #2734 2023-02-16 22:51:01 -08:00
FreeScout
3ad7123361 Fix moving conversations when merging phone customers - closes #2722 2023-02-16 22:39:16 -08:00
FreeScout
eb1b6aad4a Improve attachments mime type detection when attachment is created from remote URL 2023-02-15 23:52:25 -08:00
FreeScout
9dfad3b5cf Fix an issue when a module could not be updated due to existing Public symlink - closes #2709 2023-02-15 23:03:59 -08:00
FreeScout
4eadecc08f Delete records from followers table when the user is deleted from DB 2023-02-15 03:52:36 -08:00
FreeScout
7875faa8fd Delete records from followers table when conversation is deleted - closes #2732 2023-02-15 03:45:07 -08:00
FreeScout
35725c2718 Show extra instructions when invitation email to user can not be sent - #2730 2023-02-14 22:00:06 -08:00
FreeScout
c05722b074 mailbox.permission_users hook 2023-02-14 06:29:40 -08:00
FreeScout
8efe05e524 Merge branch 'master' of github.com:freescout-helpdesk/freescout into dist 2023-02-14 01:03:14 -08:00
FreeScout
8971b0fa5a v1.8.60 2023-02-14 01:02:21 -08:00
FreeScout
4f338b4c5f Fix passing null to strtr() in Helper::textPreview() - closes #2720 2023-02-14 00:31:44 -08:00
FreeScout
e6ae2e6f43 Add vendor files to dist 2023-02-13 23:02:02 -08:00
FreeScout
69bb79ebe8 Merge branch 'master' of github.com:freescout-helpdesk/freescout into dist 2023-02-13 22:59:48 -08:00
FreeScout
8fe5ca71cc v1.8.59 2023-02-13 22:59:09 -08:00
FreeScout
2fa094c88b Add theme-color meta filter #2719 from avenjamin/master
Add theme-color meta filter @filter
2023-02-14 08:24:31 +03:00
Avenjamin
84ab443080 Add theme-color <meta> tag @filter (typo-fixed) 2023-02-14 12:19:21 +11:00
Avenjamin
969e27a14b Add theme-color meta tag @filter
Allow overriding of the theme-color <meta> tag
2023-02-14 12:17:29 +11:00
FreeScout
6b914bae88 Fix Newer conversation button - closes #2716 2023-02-13 05:51:02 -08:00
FreeScout
562235ed8e Make validation of SMTP SSL/TLS certificate optional - closes #2714 2023-02-12 23:59:16 -08:00
FreeScout
c109a0abd6 Replace new lines with spaces in conversation previews - closes #2711 2023-02-12 00:14:53 -08:00
FreeScout
3786da3544 Set timeouts for curl and GuzzleHttp requests 2023-02-10 23:53:12 -08:00
FreeScout
a537c43c80 Do not detect image src as a customer when fetching email forwarded by support agent - closes #2672 2023-02-10 21:06:19 -08:00
FreeScout
961cadb566 Add vendor files to dist 2023-02-09 22:28:11 -08:00
FreeScout
c65f1b9295 Merge branch 'master' of github.com:freescout-helpdesk/freescout into dist 2023-02-09 22:26:03 -08:00
FreeScout
c06826bea8 v1.8.58 2023-02-09 22:25:34 -08:00
FreeScout
ea0ae16271 Save attachments when saving outgoing emails into IMAP Sent folder - closes #2699 2023-02-09 04:02:50 -08:00
FreeScout
6260c7ab82 Update Readme 2023-02-09 02:22:34 -08:00
FreeScout
2afbb0b9e2 Send alerts to all admins instead of just the first one - closes #2686 2023-02-07 22:04:06 -08:00
FreeScout
e17db42460 Add attachment paperclip to the conversation when merging - closes #2681 2023-02-06 22:35:07 -08:00
FreeScout
ef28be6ddc Make link popover disappear when the editor looses focus - closes #2678 2023-02-06 02:26:53 -08:00
FreeScout
9f57e7afa8 Merge branch 'master' of github.com:freescout-helpdesk/freescout 2023-02-06 02:26:01 -08:00
FreeScout
6a18af92d4 Fix Typos #2677 from avenjamin/master
Fix Typos
2023-02-06 13:08:23 +03:00
Avenjamin
bfc358e1a2 Fix Typos
occured => occurred
non-npublished => non-published
DEactivated => Deactivated
2023-02-06 19:45:38 +11:00
FreeScout
affe1f0fb4 Update Polish translation 2023-02-04 21:39:50 -08:00
FreeScout
7bdf758797 pt_PT language in Carbon - closes #2670 2023-02-04 21:35:06 -08:00
FreeScout
6102bda402 Add vendor files to dist 2023-02-03 00:02:49 -08:00
FreeScout
a3bbc66718 Merge branch 'master' of github.com:freescout-helpdesk/freescout into dist 2023-02-03 00:01:05 -08:00
FreeScout
3aa687ee40 v1.8.57 2023-02-03 00:00:28 -08:00
FreeScout
e2c92b03b6 Fix populating the subject when creating a New Conversation from existing message - closes #2662 2023-02-02 23:34:46 -08:00
FreeScout
27deddef1e Make cards wider - #2663 2023-02-02 05:18:48 -08:00
FreeScout
022d7e3c4a Fix making conversation Unassigned when deleting a user - closes #2660 2023-02-01 22:43:43 -08:00
FreeScout
5004da8b3c Fix some bugs when sending emails separatately to recipients - closes #2661 2023-02-01 22:19:43 -08:00
FreeScout
1b31d796d6 Fix fetching emails to multiple mailboxes at once via Cc - closes #2659 2023-02-01 09:51:33 -08:00
FreeScout
6fa54dcfa3 Remove jobs.send_notification_to_users.users hook 2023-02-01 09:29:33 -08:00
FreeScout
5fa9412f9b Sort translations when publishing 2023-02-01 05:59:25 -08:00
FreeScout
9ce7a6fcc8 Decrease Starred folder counter when discarding starred draft 2023-02-01 04:09:39 -08:00
FreeScout
71134c2627 Fix Error occured error when saving draft of a phone conversation without a customer 2023-02-01 03:40:47 -08:00
FreeScout
709c65563b Add vendor files to dist 2023-02-01 00:26:07 -08:00
FreeScout
f5f88f01a7 Merge branch 'master' of github.com:freescout-helpdesk/freescout into dist 2023-02-01 00:23:40 -08:00
FreeScout
0ec060590e v1.8.56 2023-02-01 00:23:19 -08:00
FreeScout
74aa88fd83 Import emails sent to multiple mailboxes in Bcc - closes #2652 2023-01-31 23:59:13 -08:00
FreeScout
ce6764bf26 Check conversation type when processing reply to the phone conversation 2023-01-31 22:01:39 -08:00
FreeScout
c73878f849 Add extra options to Fetch Mail Schedule - closes #2489 2023-01-31 03:46:09 -08:00
FreeScout
97aa0b7b62 jobs.send_notification_to_users.users hook 2023-01-31 01:04:26 -08:00
FreeScout
a81aa48e0e Fix deprecation errors in Illuminate/Config/Repository.php - closes #2636 2023-01-30 23:08:55 -08:00
FreeScout
d416cf05c2 Set timeouts for email sending jobs to avoid queue:work getting stuck 2023-01-30 10:31:40 -08:00
FreeScout
8be46e6ab0 Do not add multiple App\\Jobs\\RestartQueueWorker jobs when restarting queue:work 2023-01-30 03:45:36 -08:00
FreeScout
fe03177a80 Merge branch 'master' of github.com:freescout-helpdesk/freescout into dist 2023-01-30 00:44:13 -08:00
FreeScout
e9c191eb7c v1.8.55 2023-01-30 00:43:49 -08:00
FreeScout
443d0464d1 Fetch original message in the Show Original window only for customer messages 2023-01-30 00:19:08 -08:00
FreeScout
5f817043ef Fix sending reply to the customer when replying to the phone conversation - closes #2627, #2637 2023-01-30 00:07:54 -08:00
FreeScout
d465237218 Fix /img/loading.gif not found - closes #2644 2023-01-29 23:11:27 -08:00
FreeScout
2a389c5034 Change extension if uploaded PDF file contents JavaScript 2023-01-29 23:00:11 -08:00
FreeScout
e183baad7f Fix original message not being fetched in Show Original window - closes #2638 2023-01-29 21:58:04 -08:00
FreeScout
bbefab738a Fix Undefined variable $result error on fetching original message - closes #2639 2023-01-29 21:25:50 -08:00
FreeScout
93e48db1d6 Remove script tags from uploaded SVG images 2023-01-26 23:30:25 -08:00
FreeScout
23d45109e2 Escape modal titles 2023-01-26 22:30:20 -08:00
FreeScout
b0ffdfb268 Add vendor files to dist 2023-01-26 04:31:52 -08:00
FreeScout
1a75b85e9a Merge branch 'master' of github.com:freescout-helpdesk/freescout into dist 2023-01-26 04:29:46 -08:00
FreeScout
6342169f5c v1.8.54 2023-01-26 04:28:51 -08:00
FreeScout
7f0bb19134 Fix determining previous Message-ID - closes #2086 2023-01-26 04:27:08 -08:00
FreeScout
c729873e5e Fix webklex/php-imap issue with email body contained in the attachment called underfined - #1972 2023-01-26 04:22:17 -08:00
FreeScout
82180fb512 Allow to switch to the new webklex library for fetching emails via APP_NEW_FETCHING_LIBRARY env variable 2023-01-26 03:14:19 -08:00
FreeScout
f241cdbd15 Fix img proportions on purifying HTML 2023-01-26 00:46:12 -08:00
FreeScout
5ca4f39da4 Add vendor files to dist 2023-01-25 21:52:59 -08:00
FreeScout
475561cbf5 Merge branch 'master' of github.com:freescout-helpdesk/freescout into dist 2023-01-25 21:51:46 -08:00
FreeScout
71437f2778 Update composer.json 2023-01-25 21:51:33 -08:00
FreeScout
1a52f6e7c0 Merge branch 'master' of github.com:freescout-helpdesk/freescout into dist 2023-01-25 21:29:27 -08:00
FreeScout
cd8eb51131 v1.8.53 2023-01-25 21:29:00 -08:00
FreeScout
399ede2977 Update German translation 2023-01-25 21:26:59 -08:00
FreeScout
5edb1e6e9a Make HTMLPurifier PHP 8.2 compatible - closes #2623 2023-01-25 03:13:47 -08:00
FreeScout
98a391165e send_reply.before_save_forwarded_thread hook 2023-01-25 00:17:40 -08:00
FreeScout
357a9b6bfa Remove collapse and hidden classes from tables when purifying HTML - closes #2610 2023-01-25 00:06:52 -08:00
FreeScout
9c727926bc Remove collapse and hidden classes from tables when purifying HTML - closes #2610 2023-01-24 23:46:30 -08:00
FreeScout
e3ad881f5d View only allowed attachment mime types 2023-01-24 23:05:37 -08:00
FreeScout
5a26c18e84 Show corresponding message when Show Original window can not load email via IMAP - closes #2608 2023-01-24 22:26:39 -08:00
FreeScout
aea2d9794a Improve Show Original window performance - closes #2600 2023-01-24 22:06:42 -08:00
FreeScout
a3d5018c25 Do now show zero conversations in the title - closes #2613 2023-01-24 03:11:39 -08:00
FreeScout
170c4de21f Replace background: with background-color: when purifying HTML - closes #2560 2023-01-23 22:40:38 -08:00
FreeScout
78c271834b Update German translation 2023-01-23 00:54:08 -08:00
FreeScout
25f418f345 Do not distort image proportions when image is scaled using HTML.MaxImgLength - closes #2599 2023-01-23 00:39:40 -08:00
FreeScout
3c934d03af Make Swift/EmbeddedFile PHP 8.2 compatible 2023-01-22 22:51:28 -08:00
FreeScout
0d56f442ae Remove creating vendor/natxet/cssmin/src folder from composer.json 2023-01-19 21:21:44 -08:00
FreeScout
706e3fea74 Add vendor files to dist 2023-01-19 05:32:05 -08:00
FreeScout
b504bf0ecd Merge branch 'master' of github.com:freescout-helpdesk/freescout into dist 2023-01-19 05:28:54 -08:00
FreeScout
bf8ac489f0 v1.8.52 2023-01-19 05:28:02 -08:00
FreeScout
a336c5b84f Set permissions set to photo folders to 0775 2023-01-19 05:25:18 -08:00
FreeScout
76cb0d7c60 Fix missing vendor/natxet/cssmin/src folder in docker - #2583 2023-01-19 05:23:57 -08:00
FreeScout
04cd790fb1 Make RachidLaasri LaravelInstaller PHP 8.2 compatible 2023-01-19 05:17:40 -08:00
FreeScout
78b52bfb81 Fix installation after adding RestartQueueWorker::dispatch() to CleaCache 2023-01-19 05:08:02 -08:00
FreeScout
c33b770b2e Keep spaces after tags - closes #2577 2023-01-19 03:13:58 -08:00
FreeScout
b1187cbe4c Add .sidebar-no-email class if mailbox has no email 2023-01-19 01:58:32 -08:00
FreeScout
acd7e4956d Update number of active conversation in the title when new conversation arrives - closes #2576 2023-01-19 01:14:33 -08:00
FreeScout
8c28e9a2e9 Make sure Str::replaceFirst() always returns a string 2023-01-18 23:38:21 -08:00
FreeScout
3f6a9c4981 Improve temp file name generation and cleaning 2023-01-18 22:57:06 -08:00
FreeScout
898c972759 Update path to LazyOpenStream.php in composer.json 2023-01-18 22:14:06 -08:00
FreeScout
6ab04ba685 Add vendor files to dist 2023-01-18 03:37:09 -08:00
FreeScout
57f768e8ef Merge branch 'master' of github.com:freescout-helpdesk/freescout into dist 2023-01-18 03:34:13 -08:00
FreeScout
9686f12567 v1.8.51 2023-01-18 03:33:51 -08:00
FreeScout
9f0dd50969 Fix an issue when background job (queue:work) not executing 2023-01-18 03:15:17 -08:00
FreeScout
5a1c1bc648 Add small delay between connections when fetching emails to avoid mail server connections refusals - closes #2563 2023-01-18 00:06:06 -08:00
FreeScout
13889a2a84 Add slashes to models in migrations 2023-01-17 23:49:37 -08:00
FreeScout
52d02a9f62 Fix an issue when background job (queue:work) was not executed 2023-01-17 23:21:10 -08:00
FreeScout
0ca22719d8 Make sure fetching is executed even if previous command is killed or throuws an error and does not remove the mutex 2023-01-17 22:49:04 -08:00
FreeScout
3d83d7757f Automatically clean /tmp folder 2023-01-17 22:06:35 -08:00
FreeScout
ef3d8224de Update readme 2023-01-17 03:03:45 -08:00
FreeScout
b4933c20b2 Fix saving recipient when restoring draft of a forwarded message 2023-01-17 00:12:15 -08:00
FreeScout
5fb6eb9457 Fix duplicating CC and BCC when restorign a draft of a conversation with CC - clsoes #2555 2023-01-16 23:55:26 -08:00
FreeScout
d53b6bf2fc Fix restoring draf after Undo reply 2023-01-16 23:30:31 -08:00
FreeScout
ee332c38f4 Remove line from translations 2023-01-16 22:29:59 -08:00
FreeScout
07223f4c1b Update French translation 2023-01-16 22:25:01 -08:00
FreeScout
13c21868fb Fix CSS minification on PHP 8.2 2023-01-16 06:07:57 -08:00
FreeScout
27c31ad650 Update PL translation 2023-01-13 23:06:24 -08:00
FreeScout
6fba4d334b Merge branch 'master' of github.com:freescout-helpdesk/freescout into dist 2023-01-13 21:47:46 -08:00
FreeScout
c42b9fa0cb 1.8.50 2023-01-13 21:47:27 -08:00
FreeScout
6f99b2e76b Fix 2022_12_18_010101_set_user_type_field migration causing installation issues 2023-01-13 21:46:02 -08:00
FreeScout
4ef9574b56 Show Deleted folder right afer Closed folder - closes #2530 2023-01-13 21:29:53 -08:00
FreeScout
36cca92666 freescout:check-requriements command 2023-01-13 05:18:47 -08:00
FreeScout
6a3443c600 freescout:check-requriements command 2023-01-13 03:46:55 -08:00
FreeScout
542646e71a Allow to add custom headers to outgoing emails via APP_CUSTOM_MAIL_HEADERS env variable - closes #2546 2023-01-12 23:49:36 -08:00
FreeScout
a830e0440b Fix sending emails via sendmail on PHP 8.2 2023-01-12 23:36:59 -08:00
FreeScout
f1bce10ef9 Fix sending emails via mail() function on PHP 8.2 2023-01-12 23:32:08 -08:00
FreeScout
6b25822135 Hooks for general settings 2023-01-12 23:04:49 -08:00
FreeScout
279f054a2c Remove recommendation to use mail() function to send system emails from Mail Settings 2023-01-12 03:52:25 -08:00
FreeScout
3163a4103e Set proper conversation type when switching from phone to email convesation - closes #2545 2023-01-12 01:13:15 -08:00
FreeScout
609400b98f Merge branch 'master' of github.com:freescout-helpdesk/freescout into dist 2023-01-11 23:07:44 -08:00
FreeScout
5668a300e1 1.8.49 2023-01-11 23:07:08 -08:00
FreeScout
809f9cfe68 Fix an error when a user is trying to access settings of non-accessible mailbox 2023-01-11 22:56:51 -08:00
FreeScout
af6e3112d2 Do not require to enter password if user has automatically generated password - closes #2538 2023-01-11 08:42:15 -08:00
FreeScout
da3f934d35 If --no-interaction flag is passed to schedule:run the script will not run queue:work daemon - closes #2507 2023-01-10 04:37:42 -08:00
FreeScout
4f52aed496 Merge branch 'master' of github.com:freescout-helpdesk/freescout into dist 2023-01-10 00:36:52 -08:00
FreeScout
7124aa2197 v1.8.48 2023-01-10 00:36:06 -08:00
FreeScout
bc7b8f40b5 conversations.empty_folder hook 2023-01-10 00:18:28 -08:00
FreeScout
4c804ca361 Make thread_id parameter optional in Attachment->duplicate() 2023-01-09 23:56:23 -08:00
FreeScout
bd08536e54 Run RestartQueueWorker when clearing cache in order to stop queue:work to restart it when cache is cleared 2023-01-09 10:25:06 -08:00
FreeScout
eafc3d5750 Allow to add attachments to editor not only in the reply form 2023-01-09 09:18:31 -08:00
FreeScout
f9958ef526 Add comments to Kernel.php 2023-01-09 09:16:45 -08:00
FreeScout
8a4649ceae Merge branch 'master' of github.com:freescout-helpdesk/freescout into dist 2023-01-07 22:00:27 -08:00
FreeScout
132a2e28d9 v1.8.47 2023-01-07 21:59:39 -08:00
FreeScout
5b1385849f Allow to convert phone conversations into email conversations by adding email to the customer and replying 2023-01-07 21:36:46 -08:00
FreeScout
db6248ad37 Fix retrieving email from forwarded email - closes #2517 2023-01-07 02:06:31 -08:00
FreeScout
112ea66d7f Show strikethrough text in conversations - closes #2504 2023-01-05 03:11:11 -08:00
FreeScout
ab3f7a0c1e Update Czech translation 2023-01-05 01:04:08 -08:00
FreeScout
5bcfd0c726 Fix placeholder in the alert email - closes #2508 2023-01-04 02:27:22 -08:00
FreeScout
328afcbb18 Fix sending emails with attachments on PHP 8.2 - closes #2505 2023-01-04 02:18:02 -08:00
FreeScout
ec548bdaab Do not check entire HTML when processing forwarded emails - closes #2503 2023-01-04 00:57:48 -08:00
FreeScout
15f1534197 Add vendor files to dist 2023-01-02 22:47:05 -08:00
FreeScout
a04537d4ef Merge branch 'master' of github.com:freescout-helpdesk/freescout into dist 2023-01-02 22:45:51 -08:00
FreeScout
f90e48bd5d v1.8.46 2023-01-02 22:45:29 -08:00
FreeScout
31760e281b Update Czech translation 2023-01-02 22:01:20 -08:00
FreeScout
e41e098994 Fix passing null to parameter error in SwiftException.php - closes #2499 2023-01-02 21:59:37 -08:00
FreeScout
88b514dbff Improve creating tickets from forwarded emails - closes #2497 2022-12-31 05:33:06 -08:00
FreeScout
8c71c7900d Add 307 response code to Helper::downloadRemoteFileAsTmp() 2022-12-29 02:04:16 -08:00
FreeScout
54c1786435 Add exclude_hidden parameter to Mailbox::usersAssignable() 2022-12-28 10:34:00 -08:00
FreeScout
121953dc2e Merge branch 'master' of github.com:freescout-helpdesk/freescout into dist 2022-12-25 22:22:52 -08:00
FreeScout
6b0adf31be 1.8.45 2022-12-25 22:22:16 -08:00
FreeScout
6f32bb0637 Customer::byPhone() method 2022-12-25 22:18:59 -08:00
FreeScout
f18d4f0048 Improve searching customers by phone numbers 2022-12-25 21:50:10 -08:00
FreeScout
f5aba6a012 Update customer observer 2022-12-25 09:16:24 -08:00
FreeScout
2d507d498d Additionally store phone number in numeric form for customers 2022-12-25 06:33:24 -08:00
FreeScout
e90e6e4e71 Allow to disable autoreply using ar_off meta key 2022-12-24 21:58:54 -08:00
FreeScout
059b0f44dd Update link in Spread the Word footer 2022-12-23 21:54:43 -08:00
FreeScout
0df3a7ad55 Add X-Auto-Response-Suppress header to user notification emails to avoid Exchange out-of-office autoreplys - closes #2488 2022-12-23 21:18:42 -08:00
FreeScout
554a1093fb DB_PGSQL_SSLMODE env variablle - closes #2485 2022-12-23 21:07:12 -08:00
FreeScout
4e027c715f Merge branch 'master' of github.com:freescout-helpdesk/freescout into dist 2022-12-21 03:15:07 -08:00
FreeScout
3c9e2d9b3d v1.8.44 2022-12-21 03:14:47 -08:00
FreeScout
27e1aaa57f Fix set_user_type_field migration - closes #2484 2022-12-21 02:15:18 -08:00
FreeScout
29d6502c0c Fetch forwarded by support agent customer emails as tickets from customers - closes #290 2022-12-20 22:18:30 -08:00
FreeScout
28241c8e55 Pass mailbox to conversations_table from search template - closes #769 2022-12-20 04:38:54 -08:00
FreeScout
8ab1bec608 Pass mailbox to conversations_table from search template - closes #769 2022-12-20 04:27:41 -08:00
FreeScout
216ca83c22 Add vendor files to dist 2022-12-20 03:22:40 -08:00
FreeScout
256fefac59 Merge branch 'master' of github.com:freescout-helpdesk/freescout into dist 2022-12-20 03:20:15 -08:00
FreeScout
90f1349bd6 v1.8.43 2022-12-20 03:19:49 -08:00
FreeScout
e4ba051b49 Make Swiftmailer PHP 8.2 compatible 2022-12-20 00:53:41 -08:00
FreeScout
f61c482775 Fix Callables of the form Swift_SmtpTransport, Swift_Transport_EsmtpTransport::__construct are deprecated on PHP 8.2 2022-12-20 00:49:41 -08:00
FreeScout
a0384118db Button to delete all conversations from Spam - closes #1756 2022-12-20 00:06:19 -08:00
FreeScout
64b1c2bbb0 Save text after editing the code in the editor without switching back to the editor - #1705 2022-12-19 23:26:37 -08:00
FreeScout
a0b53946a0 Fetch forwarded by support agent customer emails as tickets from customers - closes #290 2022-12-19 23:03:00 -08:00
FreeScout
b39cbe7402 Merge branch 'master' of github.com:freescout-helpdesk/freescout into dist 2022-12-19 02:31:16 -08:00
FreeScout
2c3f195b96 v1.8.42 2022-12-19 02:30:56 -08:00
FreeScout
d258d04042 Fix sendin New Conversation 2022-12-19 02:30:02 -08:00
FreeScout
aa7ff00380 Merge branch 'master' of github.com:freescout-helpdesk/freescout into dist 2022-12-18 21:52:57 -08:00
FreeScout
1d6502112d 1.8.41 2022-12-18 21:49:54 -08:00
FreeScout
901fac8f89 Update PL translation 2022-12-18 21:47:48 -08:00
FreeScout
7afc9a0674 Fix error when conversation customer is changed and deleted after that - closes #2467 2022-12-18 21:46:29 -08:00
FreeScout
151f42c15d User type field 2022-12-17 22:28:44 -08:00
FreeScout
d6ef9ddc37 Add meta column to conversations table 2022-12-17 22:20:43 -08:00
FreeScout
1e39e35251 Update Readme 2022-12-16 09:36:20 -08:00
FreeScout
3181cba783 Add isset() check to SettingsController 2022-12-16 05:40:11 -08:00
FreeScout
ac19634172 In SendReplyToCustomer listener do not include messages added after the event has been fired - closes #2462 2022-12-15 22:32:36 -08:00
FreeScout
5271ba6fbf Update general_help_request.md 2022-12-15 00:43:40 -08:00
FreeScout
58e389a095 Update general_help_request.md 2022-12-14 23:47:09 -08:00
FreeScout
4894f115e0 Add vendor files to dist 2022-12-14 23:19:43 -08:00
FreeScout
f3f77c9ab5 Merge branch 'master' of github.com:freescout-helpdesk/freescout into dist 2022-12-14 23:18:32 -08:00
FreeScout
b9ebb84c0b v1.8.40 2022-12-14 23:18:15 -08:00
FreeScout
763337e7cd Prevent note remembering after sending a note and clicking Back in the browser - closes #1434 2022-12-14 22:34:54 -08:00
FreeScout
527e8241a3 Clone attachments when cloning conversations - closes #2465 2022-12-14 22:03:45 -08:00
FreeScout
154966ca8d Fix preg_replace_callback() issue on PHP 8.1 in Helper::linkify() - closes #2464 2022-12-14 21:49:10 -08:00
FreeScout
4b5d0b8232 Replace mb_convert_encoding HTML-ENTITIES in FetchEmails - closes #2461 2022-12-13 23:37:58 -08:00
FreeScout
2b87f01f90 Make javoscript/laravel-macroable-models compatible with PHP 8.2 2022-12-13 22:40:57 -08:00
FreeScout
db78c777ac Replace mb_convert_encoding HTML-ENTITIES in FetchEmails - closes #2461 2022-12-13 22:28:28 -08:00
FreeScout
85cc9924b5 Check if attachment exists on disk when sending a reply to a customer to avoid sending issues 2022-12-13 04:36:53 -08:00
FreeScout
ce33f8fbc7 Update French translation 2022-12-13 02:19:40 -08:00
FreeScout
ad63faf6ff Allow to pass an extra parameter to User::nonDeleted() function 2022-12-13 02:17:11 -08:00
FreeScout
8b5ca811dc Allow to pass an extra parameter to User::nonDeleted() function 2022-12-13 00:32:13 -08:00
FreeScout
47d988aa97 Add vendor files to dist 2022-12-12 23:22:21 -08:00
FreeScout
9ee76235fa Merge branch 'master' of github.com:freescout-helpdesk/freescout into dist 2022-12-12 23:20:18 -08:00
FreeScout
492788cca1 v1.8.39 2022-12-12 23:19:56 -08:00
FreeScout
f85c5f3969 Add data-mime attribute to attachments li element 2022-12-12 23:18:29 -08:00
FreeScout
2fbed04583 Attachment size to upper case 2022-12-12 00:45:55 -08:00
FreeScout
e4a7cd6ffd Fix site.webmanifest 401 error if FreeScout is closed with Basic authentication 2022-12-11 22:43:23 -08:00
FreeScout
097d1b7ea4 Add .attachment-link class to attachments 2022-12-11 22:42:33 -08:00
FreeScout
5e38dc9abd Fix an issue when customer was using FreeScout and reply sometimes could be connected to the wrong conversation - closes #2375 2022-12-11 05:30:13 -08:00
FreeScout
47e716239e PHP 8.2 compatibility 2022-12-10 22:20:21 -08:00
FreeScout
3a33cc03a0 .padding-right-0 class 2022-12-10 22:18:04 -08:00
FreeScout
d34f98f8db Show To dropdown when replying to a conversation with changed customer 2022-12-10 04:27:24 -08:00
FreeScout
632f3b9d4e Replace soft hyphens in attachments files - closes #2448 2022-12-10 00:42:42 -08:00
FreeScout
23c8107463 PHP 8.2 compatibility 2022-12-09 23:58:10 -08:00
FreeScout
2f79060158 Merge branch 'master' of github.com:freescout-helpdesk/freescout into dist 2022-12-09 21:52:14 -08:00
FreeScout
e107c41ce9 v1.8.38 2022-12-09 21:51:53 -08:00
FreeScout
ddab271fce Rename mailbox.before_name hooks 2022-12-09 03:31:27 -08:00
FreeScout
13428f1526 Allow to show errors in the mailbox settings form via hooks 2022-12-09 03:30:25 -08:00
FreeScout
d02ce264ea Rename mailbox.before_name hooks 2022-12-08 22:55:30 -08:00
FreeScout
367b79687e Created Followers observer 2022-12-07 22:57:12 -08:00
FreeScout
0201523656 Jump to the conversation when searching by conversation number 2022-12-07 22:34:54 -08:00
FreeScout
96b0c17bc8 Rename MYSQL_ATTR_SSL_CA attr into DB_MYSQL_ATTR_SSL_CA 2022-12-07 21:22:37 -08:00
FreeScout
38fcc96c23 Add config to connect mysql/mariadb over TLS #2446 from mzch/master
Add config to connect mysql/mariadb over TLS
2022-12-07 17:32:26 +03:00
Koichi MATSUMOTO
f10b8e1526 Add config to connect mysql/mariadb over TLS
Add config to connect mysql/mariadb over TLS.
2022-12-07 23:26:53 +09:00
FreeScout
1d57be2fa0 Merge branch 'master' of github.com:freescout-helpdesk/freescout into dist 2022-12-07 06:04:53 -08:00
FreeScout
353774b83f v1.8.37 2022-12-07 06:04:13 -08:00
FreeScout
76e29a0b3d Add auto-reply header to Mail::isAutoResponder() - closes #2445 2022-12-07 06:02:39 -08:00
FreeScout
5e1537a217 Add auto-reply header to Mail::isAutoResponder() - closes #2445 2022-12-07 05:59:27 -08:00
FreeScout
368c6fdd64 Use case insensitive search for customers in PostgreSQL 2022-12-07 05:36:31 -08:00
FreeScout
b460bf2c14 Fix searching by customer name 2022-12-06 22:59:19 -08:00
FreeScout
d2c2b1837c Allow to sort search results by columns 2022-12-06 22:51:16 -08:00
FreeScout
66d45bf7f6 Entities hooks 2022-12-06 22:39:42 -08:00
FreeScout
ae861da89d Search hooks 2022-12-06 22:39:27 -08:00
FreeScout
c38438c317 Attachment observer 2022-12-06 22:38:24 -08:00
FreeScout
c8737b859a Make search case insensitive on PostgreSQL 2022-12-02 20:54:08 -08:00
FreeScout
3448df8087 Fix search when searching in a specific mailbox 2022-12-02 05:54:54 -08:00
FreeScout
76b32e28f5 Change ilike to like in the search 2022-12-02 05:41:56 -08:00
FreeScout
34883489c9 Search improvements #2434 from calebbaker194/master
Search improvements
2022-12-02 16:36:54 +03:00
FreeScout
c32c06819d New customer and thread functions 2022-12-01 22:32:59 -08:00
FreeScout
eb17935278 Update readme 2022-12-01 22:32:46 -08:00
Caleb
3914c87c71 Search improvments
This will allow searching by customer first and last name to find threads or customers. It also ignores cases on more things.
2022-12-01 08:21:25 -06:00
FreeScout
cc3f44d5e7 Allow users delete their notes 2022-11-30 05:51:40 -08:00
FreeScout
9238f97b87 Fix Call to a member function getFirstName() on null - closes #2432 2022-11-30 05:37:25 -08:00
FreeScout
8fc5372c91 Improve Clone Conversation implementation 2022-11-30 03:29:13 -08:00
FreeScout
00cb9bde18 Add possibility to clone a conversation #2430 from kovoks/master
Add possibility to clone a conversation.
2022-11-30 11:33:35 +03:00
FreeScout
29408872ee Remove sass installer files 2022-11-29 23:04:51 -08:00
FreeScout
fc4cf0e482 Update readme 2022-11-29 22:56:45 -08:00
Tom Albers
6e60f4b0dd Add possibility to clone a conversation. 2022-11-29 20:30:27 +01:00
FreeScout
440177eaa5 Add vendor files to dist 2022-11-27 05:51:52 -08:00
FreeScout
ce09e3e287 Merge branch 'master' of github.com:freescout-helpdesk/freescout into dist 2022-11-27 05:48:58 -08:00
FreeScout
40b61379fa v1.8.36 2022-11-27 05:48:00 -08:00
FreeScout
69329ce86d getMainPhoneValue() and getMainWebsite() method for Customer 2022-11-27 05:46:30 -08:00
FreeScout
eff45a28a4 Remove limitation on database connection parameters length on installation - closes #2418 2022-11-27 05:46:01 -08:00
FreeScout
d721a49ab4 Update javascript hook 2022-11-27 00:34:46 -08:00
FreeScout
96d31fc723 Do no show conversations from all mailboxes when the users has no mailboxes assigned - closes #2409 2022-11-25 22:06:56 -08:00
FreeScout
270e0b5da8 Fix PHP 81 error in FormatsMessages.php 2022-11-25 22:01:51 -08:00
FreeScout
8f23ba8872 Fix PHP81 error on saving mailbox outgoing settings - closes #2401 2022-11-25 21:53:30 -08:00
FreeScout
260671922b Change undefined attachment name to RFC822.eml for Webklex php-imap - closes #2385 2022-11-22 00:54:32 -08:00
FreeScout
4c3fe87a5f Fix PostgreSQL migration on PHP8.1 - closes #2401 2022-11-22 00:52:14 -08:00
FreeScout
bb912ca149 Fix Passing null to parameter in Translate page - closes #2398 2022-11-18 21:09:41 -08:00
FreeScout
98e0ae0f05 Do not log empty email body notice 2022-11-17 00:35:25 -08:00
FreeScout
7813210078 Add vendor files to dist 2022-11-16 23:30:17 -08:00
FreeScout
c51ee20010 Merge branch 'master' of github.com:freescout-helpdesk/freescout into dist 2022-11-16 23:27:22 -08:00
FreeScout
d11c09b3de v1.8.35 2022-11-16 23:26:41 -08:00
FreeScout
4a723d4abb Update webklex php-imap lirary to the latest version to fix empty body on MS365 - closes #1972 2022-11-16 23:25:07 -08:00
FreeScout
eb42948fa0 Save summernote cursor positino on reply area blur 2022-11-16 22:25:08 -08:00
FreeScout
481970fd65 Merge branch 'master' of github.com:freescout-helpdesk/freescout into dist 2022-11-16 08:56:07 -08:00
FreeScout
a9b84ac58d v1.8.34 2022-11-16 08:55:35 -08:00
FreeScout
4be8d83314 Fix To, Cc, Bcc fields - closes #2388 2022-11-16 08:54:39 -08:00
FreeScout
a7489e8679 Merge branch 'master' of github.com:freescout-helpdesk/freescout into dist 2022-11-16 04:04:38 -08:00
FreeScout
593439faf5 v1.8.33 2022-11-16 04:03:59 -08:00
FreeScout
6500b9e510 Fix Passing null to parameter to nl2br in FetchEmail - closes #2387 2022-11-16 03:42:08 -08:00
FreeScout
a9f055dc21 Do not crop mailbox dropdown menu - closes #2252 2022-11-15 02:23:22 -08:00
FreeScout
0d78f5db73 Save summernote cursor positino on reply area blur 2022-11-13 22:07:04 -08:00
FreeScout
429575f5f8 Fix Passing null to parameter in Helper::linkify() 2022-11-13 21:59:42 -08:00
FreeScout
36c6d3418e Do not allow to search conversations and customers in mailboxes to which the user have no access - closes #2370 2022-11-12 23:47:02 -08:00
FreeScout
b3ba614d9f Update Polish translation 2022-11-09 23:07:54 -08:00
FreeScout
587e836031 Remove new lines from envelope when saving outgoing email - closes #2376 2022-11-09 23:07:03 -08:00
FreeScout
747a13ac8c Show base64 data images in conversations 2022-11-09 22:54:35 -08:00
FreeScout
2ef4bc40a5 Show base64 data images in conversations - closes #2355 2022-11-09 22:53:08 -08:00
FreeScout
9570399ab9 Merge branch 'master' of github.com:freescout-helpdesk/freescout into dist 2022-11-09 02:18:31 -08:00
FreeScout
ee68d9b149 v1.8.32 2022-11-09 02:17:35 -08:00
FreeScout
645ac3187a Allow to prefill the subjection via GET parameter when creating a conversation - closes #2360 2022-11-09 00:43:54 -08:00
FreeScout
765e9a4e08 Do not allow to search conversations and customers in mailboxes to which the user have no access - closes #2370 2022-11-09 00:34:34 -08:00
FreeScout
3c33a6900e Search for tickets assigned to Anyone #2368 from Xuf00/unassigned-search-patch
Search for tickets assigned to Anyone - fixes #2367
2022-11-09 11:01:38 +03:00
FreeScout
0424a3869f French translation corrections #2366 from e-rwan/master
French translation corrections
2022-11-09 11:00:39 +03:00
Jack Johnson
a17716f2e4 Add support for searching for tickets that are assigned to the "Anybody" user 2022-11-06 20:21:41 +00:00
e-rwan
ac39d3385b Update fr.json 2022-11-04 16:31:30 +01:00
e-rwan
520a386717 Update fr.json 2022-11-04 16:29:44 +01:00
e-rwan
acda86eedf Update fr.json 2022-11-04 16:26:47 +01:00
e-rwan
c865af543b Update fr.json 2022-11-04 13:12:43 +01:00
FreeScout
1739602bdf Conversation table hooks 2022-10-26 23:26:20 -07:00
FreeScout
e2a5e5c021 Merge branch 'master' of github.com:freescout-helpdesk/freescout into dist 2022-10-25 00:27:33 -07:00
FreeScout
201d5a6f86 v1.8.31 2022-10-25 00:26:49 -07:00
FreeScout
13bca95e3c View Details button for failed jobs - closes #2044 2022-10-25 00:23:15 -07:00
FreeScout
54d4ceadd1 Improve email validation - closes #2338 2022-10-24 22:50:21 -07:00
FreeScout
05be407f37 Improve email validation - closes #2338 2022-10-24 04:35:23 -07:00
FreeScout
8b23ece688 Fix passing null parameter to Mail::hasVars() - closes #2335 2022-10-23 23:06:26 -07:00
FreeScout
460bc17e36 Fix Attempt to assign property user_updated_at on null 2022-10-23 07:03:02 -07:00
FreeScout
70fdbcdb66 Do not limit line length in getBodyAsText() 2022-10-15 01:31:55 -07:00
FreeScout
7b8a202131 Hide from Assign list users who are hidden in mailbox settings - closes #2327 2022-10-15 00:34:45 -07:00
FreeScout
b38a7f49fd Set system timezone for new users upon creation - closes #2312 2022-10-15 00:28:53 -07:00
FreeScout
ae384e035b Update general_help_request.md 2022-10-15 00:20:34 -07:00
FreeScout
25c43247cf Merge branch 'master' of github.com:freescout-helpdesk/freescout into dist 2022-10-13 04:27:46 -07:00
FreeScout
5e6d6f0d2c v1.8.30 2022-10-13 04:26:05 -07:00
FreeScout
883c0696e7 editorProcessInsertVar() function 2022-10-13 04:22:34 -07:00
FreeScout
2d7fc4deb5 Allow to pass modal options to triggerModal() function 2022-10-13 01:29:33 -07:00
FreeScout
e1008951b5 Add Greek reply separator #2319 from fulldecent/patch-11
Add Greek reply separator, fixes #882
2022-10-12 08:27:56 +03:00
William Entriken
659382d41b Add localized separator, fixes #882 2022-10-11 14:33:53 -04:00
FreeScout
41a0e0f205 Preserve table classes when filtering email content - closes #2308 2022-10-07 06:41:24 -07:00
FreeScout
098b830a08 Merge branch 'master' of github.com:freescout-helpdesk/freescout into dist 2022-09-28 22:17:00 -07:00
FreeScout
ce05a79574 v1.8.29 2022-09-28 22:16:19 -07:00
FreeScout
d41000fb8d Improve including email address of original sender when forwarding conversation - closes #2285 2022-09-28 10:56:33 -07:00
FreeScout
e93bf6a121 Merge branch 'master' of github.com:freescout-helpdesk/freescout into dist 2022-09-27 07:06:39 -07:00
FreeScout
21427aa533 v1.8.28 2022-09-27 07:06:05 -07:00
FreeScout
ba397bbff9 Allow to forward chat conversations - closes #2280 2022-09-27 07:04:31 -07:00
FreeScout
49331ccf19 Rename /tools/pre_upgrade.sh into /tools/pre_update.sh and add post_update.sh - closes #2282 2022-09-27 06:58:11 -07:00
FreeScout
80498f7e66 Update eneral_help_request.md 2022-09-26 23:38:18 -07:00
FreeScout
c5128990bd Fix grammar application better #2278 from fulldecent/fix-grammar-application-better
Fix grammar application better
2022-09-27 09:19:48 +03:00
William Entriken
5e700de7fd Grammar fix 2022-09-26 15:31:12 -03:00
FreeScout
380ea308b3 Include emailaddress of original sender when forwarding conversation - closes #1236 2022-09-25 00:01:54 -07:00
FreeScout
0bbdd3eeeb Shorten forward_ meta fields 2022-09-24 23:37:42 -07:00
FreeScout
ff98192d92 notifications_table.td hook 2022-09-24 06:44:00 -07:00
FreeScout
25c832ffae flash_messages.flashes hook 2022-09-24 06:43:43 -07:00
FreeScout
da75d733d5 .subs-cb style for subscriptions table 2022-09-24 06:35:55 -07:00
FreeScout
03fd7c33ce notifications_table.th and notifications_table.td hooks 2022-09-23 02:01:13 -07:00
FreeScout
a0e169e92c conversation.status_changing hook 2022-09-23 01:20:31 -07:00
FreeScout
ae6fa8e7b2 Merge branch 'master' of github.com:freescout-helpdesk/freescout into dist 2022-09-22 05:21:21 -07:00
FreeScout
bf20ea5647 v1.8.27 2022-09-22 05:19:37 -07:00
FreeScout
6f4dd9b457 user.edit.phone_append hook 2022-09-22 05:18:26 -07:00
FreeScout
03a2e9789d Add Azerbaijani language to the Translate page - closes #2269 2022-09-22 02:40:26 -07:00
FreeScout
b0f8f9ebc3 Improve placing an outgoing email to the IMAP folder - closes #1892 2022-09-22 02:37:00 -07:00
FreeScout
fb47dd5c88 Update Russian translation 2022-09-22 02:07:57 -07:00
FreeScout
36ee900d8a Rename PublicController into OpenController to fix translating - closes #2268 2022-09-22 01:52:52 -07:00
FreeScout
fde6f0d0af Add alt attribute to images in the editor - closes #2265 2022-09-22 00:56:41 -07:00
FreeScout
168c61e4b0 Merge branch 'master' of github.com:freescout-helpdesk/freescout into dist 2022-09-21 04:18:20 -07:00
FreeScout
cc38f1482c v1.8.26 2022-09-21 04:17:40 -07:00
FreeScout
83392b81a5 url_generator.app_url hook 2022-09-21 00:30:29 -07:00
FreeScout
4617b50bf0 Follow redirects in Helper::downloadRemoteFileAsTmp() 2022-09-19 23:17:27 -07:00
FreeScout
0cc2787d3c Fix setting a conversation Preview when a conversation is created outside of web interface - closes #2254 2022-09-17 06:55:20 -07:00
FreeScout
3796cff48d Allow all users to mute notifications from particular mailboxes 2022-09-17 05:36:42 -07:00
FreeScout
350b09a77c Merge branch 'master' of github.com:freescout-helpdesk/freescout into dist 2022-09-17 02:42:27 -07:00
FreeScout
28c3bb7053 v1.8.25 2022-09-17 02:41:44 -07:00
FreeScout
66fa46f937 conversation.state_changed hook 2022-09-17 02:39:41 -07:00
FreeScout
e639827cbe Adjust parseDateToCarbon() helper function 2022-09-16 22:15:19 -07:00
FreeScout
45e992d65b Fix unchecking all default subscriptions - closes #2247 2022-09-16 07:53:39 -07:00
FreeScout
ebcd11aae9 Avoid fatal error when conversation status is zero - closes #2237 2022-09-16 06:43:43 -07:00
FreeScout
b65373b837 APP_PROXY variable - closes #2242 2022-09-16 06:33:47 -07:00
FreeScout
9dbc09cccd Add iconv to the list of required extensions - closes #2236 2022-09-16 06:21:09 -07:00
FreeScout
3ba5b6b727 Remove white color background from #conv-layout- elements 2022-09-14 07:35:02 -07:00
FreeScout
137a714e06 Set fixed white color for .fs-tag 2022-09-14 07:23:23 -07:00
FreeScout
cc8f94fcff Merge branch 'master' of github.com:freescout-helpdesk/freescout into dist 2022-09-14 04:19:42 -07:00
FreeScout
4e6fd62f62 v1.8.24 2022-09-14 04:19:00 -07:00
FreeScout
29dfd29937 Fix Passing null to parameter in http-foundation/Response.php - closes #2223 2022-09-14 01:47:26 -07:00
FreeScout
a7cc9b4145 Fix strtolower: Passing null to parameter in swift MimePart.php 2022-09-14 00:45:55 -07:00
FreeScout
c3fc12f773 mail.reapply_mail_config hook 2022-09-14 00:08:28 -07:00
FreeScout
6056b05b0f Adjust conversations navigation colspan 2022-09-12 10:25:51 -07:00
FreeScout
b395320ffd Make conversation history table wider in customer profile #2224 from fulldecent/patch-9
Make conversation history table wider in customer profile, Fix #61
2022-09-12 19:45:56 +03:00
William Entriken
6cae742920 Fix #61 2022-09-12 12:07:14 -04:00
FreeScout
37997583c9 deleteCustomer() method 2022-09-12 00:25:17 -07:00
FreeScout
990f05bc7d body.class hook 2022-09-11 01:01:22 -07:00
FreeScout
e130611866 deleteCookie() funciton 2022-09-11 00:00:35 -07:00
FreeScout
c3fe512dac Fetch emails by bunches in order to allow fetch large amounts of emails - closes #2198 2022-09-09 04:58:26 -07:00
FreeScout
8443713d48 Allowing multiple summernote hints #2202 from FreeScout-shop/master
Allowing multiple summernote hints
2022-09-09 11:44:29 +03:00
FreeScout
b850065299 Merge branch 'master' of github.com:freescout-helpdesk/freescout into dist 2022-09-09 00:40:31 -07:00
FreeScout
58720634cc v1.8.23 2022-09-09 00:39:43 -07:00
FreeScout
ddd853d5dc Fix searching convesations in the Merge dialog window 2022-09-09 00:35:19 -07:00
FreeScout
09c1bfa20a Fix searching conversations by number 2022-09-09 00:30:48 -07:00
RienNeVaPlus
0cfd2ba284 Initialize summernote.options.hint as [] 2022-09-07 06:08:05 +02:00
FreeScout
a32e4bb3a4 Preserve column sorting when using conversations navigation - closes #2191 2022-09-03 22:13:32 -07:00
FreeScout
56905d3187 conversation.prepend_send_dropdown hook 2022-09-03 22:12:28 -07:00
FreeScout
b7e83c7fd6 Follow a conversation when replying to a conversation assigned to someone else 2022-09-02 23:38:53 -07:00
FreeScout
8b6afcefd5 Show bell icon in the subject of conversations you are following 2022-09-02 23:10:27 -07:00
FreeScout
9e71085823 Merge branch 'master' of github.com:freescout-helpdesk/freescout into dist 2022-09-02 22:25:19 -07:00
FreeScout
d5ea944357 v1.8.22 2022-09-02 22:24:43 -07:00
FreeScout
483abee1ae user.non_deleted_condition hook 2022-09-02 22:17:03 -07:00
FreeScout
244224ac9b Take into account mailbox Default Assignee option when user replies to the notification by email - #2153 2022-09-02 09:59:07 -07:00
FreeScout
0916597990 Merge pull request #2169 from ilyakonovalenko/master
New action before_prev_convs per issue #2167 + An ability to keep current status and assignee per issue #2180
2022-09-02 17:39:20 +03:00
FreeScout
685b5abe03 Show proper error message when trying to forward a conversation without specifying a To address - closes #2189 2022-09-02 07:09:54 -07:00
FreeScout
1535fc69dc Check fpassthru() function in System Status - closes #597 2022-09-02 06:49:29 -07:00
FreeScout
d7a6260e2c Change lockout timeout to 10 minutes on Too many login attempts - closes #2135 2022-09-02 06:47:07 -07:00
FreeScout
584cf3bcea Fix decoding binary encoded emails - clsoes #2186 2022-09-02 06:36:41 -07:00
FreeScout
2c5be3a77e Check required functions in the installer - closes #2187 2022-09-02 04:47:07 -07:00
Илья Коноваленко
5de121a000 Added an ability to keep current conversation status and assignee when replying via both FreeScout and email 2022-08-30 12:54:52 +05:00
Илья Коноваленко
bd8e80510e Adding new action before_prev_convs per issue #2167 2022-08-20 00:28:46 +05:00
FreeScout
b235016207 Fix locking out - closes #2135 2022-08-18 00:51:40 -07:00
FreeScout
5befe9f1d7 Improve coding standard of x_embed commit 2022-08-17 23:48:47 -07:00
FreeScout
26b50243af Fixes for UI issues for conversation display via x_embed #2156 from vtq221/master
Changes for #2141 - Fixes for UI issues for conversation display via x_embed
2022-08-18 09:42:13 +03:00
FreeScout
70a3e0e500 Update notifications_table.general.append hook 2022-08-17 23:35:40 -07:00
FreeScout
97dbbd22b0 Update Danish translation 2022-08-17 02:51:36 -07:00
FreeScout
4bc8741dbc Set default empty preview in Conversation 2022-08-17 02:50:59 -07:00
vtq
20ade30be8 Changes for #2141 - fixes for UI issues for conversation display in kanban 2022-08-14 11:09:14 +10:00
FreeScout
5a8bcaf0ac Make conversation number equal to conversation ID by default - closes #2076 2022-08-01 08:04:22 -07:00
FreeScout
87dfcb8ed0 Merge branch 'master' of github.com:freescout-helpdesk/freescout into dist 2022-08-01 04:41:01 -07:00
FreeScout
f54e9e9e5d v1.8.21 2022-08-01 04:40:22 -07:00
FreeScout
28e75dbfbc Fix adding Re: to the subject - closes #2125 2022-08-01 04:39:18 -07:00
FreeScout
407c4a499d Fix modules list if author URL is empty on PHP 8.1 - closes #2127 2022-08-01 01:23:22 -07:00
FreeScout
9fe3b80fbf Corrected default customer avatar image URL to work with subdirectory #2122 from virtiqa/master
Corrected default customer avatar image URL to work with subdirectory
2022-08-01 08:59:59 +03:00
vtq
ef0fbccb12 Corrected default customer avatar image URL to work with subdirectory installs #2121 2022-07-28 20:06:13 +10:00
FreeScout
7a0921765a Removed trailing slash from tracking pixel route #2112 from virtiqa/master
Fix for #2111 removed trailing slash from tracking pixel route
2022-07-25 13:26:11 +03:00
vtq
ee2d752e25 Fix for #2111 removed trailing slash from tracking pixel route 2022-07-25 15:58:45 +10:00
FreeScout
5363501c98 Do not log in user automatically after resettings the password 2022-07-24 06:54:38 -07:00
FreeScout
aedb19901b Allow to delete mailboxes with unlimited number of conversations - closes #2089 2022-07-24 06:28:32 -07:00
FreeScout
44a1103210 Allow to delete unlimited number of conversations from Trash 2022-07-24 06:22:56 -07:00
FreeScout
78a1c8d249 Allow to fetch emails via POP3 2022-07-24 03:35:32 -07:00
FreeScout
495704cf41 Update Spanish translation 2022-07-24 03:24:40 -07:00
FreeScout
4698605a70 Default folder INBOX (POP3 fix) #2093 from PysX/master
Default folder INBOX (POP3 fix)
2022-07-24 12:30:28 +03:00
Cédric NOËL
2b0a31008b Default folder INBOX 2022-07-12 15:59:36 +02:00
FreeScout
4c4db724a5 Merge branch 'master' of github.com:freescout-helpdesk/freescout into dist 2022-07-06 10:57:59 -07:00
FreeScout
c4f5c234ae v1.8.20 2022-07-06 10:57:28 -07:00
FreeScout
70034bab61 Allow to bypass caching in Option::get() 2022-07-02 22:10:13 -07:00
FreeScout
eed54ed526 Merge branch 'master' of github.com:freescout-helpdesk/freescout 2022-07-01 23:04:59 -07:00
FreeScout
7728658175 Small optimizations to better style dashboard cards and sidebar folders #2073 from FreeScout-shop/master
Small optimizations to better style dashboard cards and sidebar folders
2022-07-02 09:04:07 +03:00
RienNeVaPlus
3f133c868d Add icon as class name and $active_count as data attribute 2022-07-01 06:34:58 +02:00
RienNeVaPlus
029d26b5af Add data-mailbox-id attribute to dash card 2022-07-01 06:33:03 +02:00
FreeScout
d0084862b7 Rename mailboxes.update_after_signature hook into mailbox.update.after_signature 2022-06-30 04:46:32 -07:00
FreeScout
5ded7d579a When emptying trash update starred conversations counter 2022-06-30 01:04:17 -07:00
FreeScout
758033a230 When deleting conversation forever delete them also from conversation_folder table 2022-06-30 01:03:40 -07:00
FreeScout
e8ae4e306f Update label text in tools.php 2022-06-30 00:16:03 -07:00
FreeScout
a3318986d7 Updated apple-touch-icon #2065 from ybizeul/new-apple-touch-icon
Updated apple-touch-icon
2022-06-30 10:05:39 +03:00
FreeScout
1c98d1602b Fix error in isLocaleRtl() if app.locales_rtl is empty - closes #2072 2022-06-30 00:04:28 -07:00
Yann Bizeul
2db5177e23 Updated apple-touch-icon 2022-06-27 07:44:18 +02:00
FreeScout
ebdb9f8979 Update Readme 2022-06-21 23:10:57 -07:00
FreeScout
fe4c69e3a9 Merge branch 'master' of github.com:freescout-helpdesk/freescout into dist 2022-06-20 00:13:22 -07:00
FreeScout
d961797c40 v1.8.19 2022-06-20 00:12:17 -07:00
FreeScout
b8dd8d30a6 Allow to log in in the mobile app when the root is redirecting - closes #2039 2022-06-19 23:55:22 -07:00
FreeScout
213fb80f95 Preservce code blocks when editing threads 2022-06-19 06:00:58 -07:00
FreeScout
7531eb4d64 Update Czech translation 2022-06-18 03:23:23 -07:00
FreeScout
f7c9d08b6c Pass conversation to conversation.is_in_folder_allowed hook 2022-06-17 22:29:31 -07:00
FreeScout
31995613ba mailbox.incoming_settings_before_save hook 2022-06-17 10:49:40 -07:00
FreeScout
529df15375 fetch_emails.after_set_seen hook 2022-06-17 10:48:59 -07:00
FreeScout
abfbf9959a Merge branch 'master' of github.com:freescout-helpdesk/freescout into dist 2022-06-14 23:43:31 -07:00
FreeScout
9caa1e10cc v1.8.18 2022-06-14 23:43:03 -07:00
FreeScout
81139ab8b2 Adjust customer form and snippet 2022-06-14 23:41:56 -07:00
FreeScout
5f0510484e Enhancement of customer form #2034 from nykopol/master
Enhancement of customer form
2022-06-15 09:24:03 +03:00
FreeScout
c87b3a97d7 Do not send notifications to deleted users 2022-06-14 00:18:50 -07:00
FreeScout
74712cf2d9 search.assignees filter 2022-06-14 00:18:35 -07:00
FreeScout
40e0776219 Update subscription hooks 2022-06-10 02:39:19 -07:00
FreeScout
dc1d3ec5da Add EMAIL_DELETED_SUFFIX constatnt to User 2022-06-09 23:54:29 -07:00
FreeScout
d72bc81563 mailbox.permissions.before_access_settings hook 2022-06-09 05:13:41 -07:00
FreeScout
4d3bddc4d2 Folder meta functions 2022-06-09 05:13:23 -07:00
FreeScout
3cdbeaa768 Subscription hooks 2022-06-09 01:41:30 -07:00
FreeScout
13a9ca2ff3 User mailbox access hooks 2022-06-09 00:00:08 -07:00
Johan Desmyter
53f6c18cbe edit and show the existing phone type information on customer 2022-06-08 15:08:49 +03:00
Johan Desmyter
3211037aba add basic html validation on customer form 2022-06-08 13:59:26 +03:00
FreeScout
f5bf5afe14 Add vendor files to dist 2022-06-06 22:44:49 -07:00
FreeScout
4f65bbc723 Merge branch 'master' of github.com:freescout-helpdesk/freescout into dist 2022-06-06 22:43:19 -07:00
FreeScout
56e8e3862b v1.8.17 2022-06-06 22:42:54 -07:00
FreeScout
0d53e23151 Allow acess to /.well-known on Apache 2022-06-06 22:25:50 -07:00
FreeScout
dcdc372e45 Fix Passing null to parameter in User - closes #2020 2022-06-05 03:21:31 -07:00
FreeScout
ca847752df Third-party modules section in Modules 2022-06-03 11:04:50 -07:00
FreeScout
6156dc0824 Fix creating phone conversation on PHP 8.1 - closes #2028 2022-06-03 03:06:30 -07:00
FreeScout
04374dccdf Authentication hooks 2022-06-03 01:49:26 -07:00
FreeScout
1e4e67cc37 Hooks for URL in user email notifications 2022-06-03 01:47:47 -07:00
FreeScout
338df4aa44 Add Korean language 2022-06-01 04:51:09 -07:00
FreeScout
fc24702844 Implement IMAP Folder To Save Outgoing Replies for oAuth IMAP connection - closes #2018 2022-06-01 04:36:51 -07:00
FreeScout
fb82f16ef6 Merge pull request #2022 from e1mo/e1mo/app-key-file
Add APP_KEY_FILE environment variable
2022-06-01 12:53:52 +03:00
Moritz 'e1mo' Fromm
d915c646bb Add APP_KEY_FILE environment variable
In lots environments having files with secrets is common (e.g. with
NixOS where static secrets in config files are not secure). This new
environment variable adds support for this. If a APP_KEY is defined it
will take precedence ofer APP_KEY_FILE
Tests have been added to show this beaviour.
2022-05-31 17:33:52 +02:00
FreeScout
400ec40ff1 Added Czech language 2022-05-29 22:52:55 -07:00
FreeScout
d73f64b669 Update Polish language 2022-05-26 03:25:17 -07:00
FreeScout
403a160917 Merge branch 'master' of github.com:freescout-helpdesk/freescout into dist 2022-05-24 02:43:01 -07:00
FreeScout
3904e6d120 v1.8.16 2022-05-24 02:42:28 -07:00
FreeScout
bcdc2e793e Hooks for mailbox icons and customer default avatar #2012 from RienNeVaPlus/master
Hooks for mailbox icons and customer default avatar
2022-05-24 12:41:30 +03:00
FreeScout
cc68ee3d27 Avoid customer reply duplication loop - closes #2003 2022-05-24 02:38:41 -07:00
RienNeVaPlus
0b0ad5067c Fix argument of filter customer.default_avatar 2022-05-24 11:15:18 +02:00
RienNeVaPlus
b391d4496c Rename action to mailbox.update.before_name 2022-05-24 11:13:57 +02:00
FreeScout
31df77a0b9 Fix fetching issues 2022-05-24 01:30:19 -07:00
RienNeVaPlus
5e053d2954 Add action mailbox.before_name 2022-05-24 09:42:07 +02:00
RienNeVaPlus
3cfa02fde2 Add action mailbox.before_name 2022-05-24 09:40:51 +02:00
RienNeVaPlus
e3a5ac1432 Add action mailbox.before_name 2022-05-24 09:39:57 +02:00
RienNeVaPlus
97abf1da76 Add action mailbox.before_name 2022-05-24 09:39:03 +02:00
RienNeVaPlus
1a28d142f2 Add action mailbox.before_name 2022-05-24 09:38:01 +02:00
RienNeVaPlus
6dcd0dc8cc Allow file uploads in mailbox update form 2022-05-24 09:36:35 +02:00
RienNeVaPlus
23d812cdd4 Add action mailbox.update_before_name 2022-05-24 09:35:59 +02:00
RienNeVaPlus
90270ad31f Add filter customer.default_avatar 2022-05-24 09:34:03 +02:00
FreeScout
5ed8d90c70 Add [Third-Party] suffix to third-party modules 2022-05-16 23:22:06 -07:00
FreeScout
1f2182d014 Add [Third-Party] suffix to third-party modules 2022-05-16 22:11:08 -07:00
FreeScout
c1a2b819ec Merge branch 'master' of github.com:freescout-helpdesk/freescout into dist 2022-05-16 21:44:37 -07:00
FreeScout
2b8e3fda63 v1.8.15 2022-05-16 21:44:09 -07:00
FreeScout
8bb0988010 Allow passwords with spaces during installation - closes #1998 2022-05-16 07:20:53 -07:00
FreeScout
5c4eaa17cf Fix Canada/Newfoundland timezone name - closes #1997 2022-05-16 07:01:41 -07:00
FreeScout
4bb44a8d1a Fix Call to a member function sortBy() on array on fetching emails - closes #1984 2022-05-16 06:55:21 -07:00
FreeScout
826418d5e4 Merge branch 'master' of github.com:freescout-helpdesk/freescout into dist 2022-05-13 00:08:55 -07:00
FreeScout
c2810be1b8 v1.8.14 2022-05-13 00:08:21 -07:00
FreeScout
3243d57b01 editor.vars hook 2022-05-12 22:57:13 -07:00
FreeScout
9bf1637320 User setData() method 2022-05-12 04:22:55 -07:00
FreeScout
ae415033dd Improve modules activation process 2022-05-11 02:19:07 -07:00
FreeScout
41d2743816 Fix Undefined property conversation in SendEmailReplyError job - closes #1974 2022-05-11 02:02:35 -07:00
FreeScout
2e6eb810cd Fix searching Phone conversations - closes #1986 2022-05-11 01:56:22 -07:00
FreeScout
7f99ef2c74 Fix PHP81 issue on deactivating a license 2022-05-10 04:39:23 -07:00
FreeScout
fda79460b8 Fix typo in update.sh #1977 from Pablohn26/patch-1
Fix typo in update.sh
2022-05-06 10:34:44 +03:00
Pablo Hinojosa
b91155c2ce Fix typo 2022-05-05 20:03:58 +02:00
FreeScout
83e2b0af7f Improve error message when user replies from random email address - #1971 2022-05-05 04:23:42 -07:00
FreeScout
d82b3dc896 Set SERVER HTTPS variable if needed in HttpsRedirect middleware 2022-05-03 22:47:27 -07:00
FreeScout
7f732bcfef Fix closed folder sorting - #1965 2022-05-03 03:55:29 -07:00
FreeScout
32a6c46e8a Merge branch 'master' of github.com:freescout-helpdesk/freescout into dist 2022-05-01 04:51:25 -07:00
FreeScout
097615ef69 v1.8.13 2022-05-01 04:50:50 -07:00
FreeScout
ebaddd76a7 Allow to change Default Redirect from mailbox dropdown menu - closes #1942 2022-04-30 03:43:35 -07:00
FreeScout
aa4105e0cd Show error in the log when fetching from custom IMAP folder - closes #1961 2022-04-30 01:39:09 -07:00
FreeScout
487e0bf370 Update translations 2022-04-30 01:25:55 -07:00
FreeScout
8121c489d5 Update Gmail instruction link 2022-04-29 23:26:33 -07:00
FreeScout
3362bbeb45 Update general_help_request 2022-04-29 23:25:53 -07:00
FreeScout
08796da55e Make some modifications in RTL style to fix view issues #1945 from rhashnull/master
Make some modifications in RTL style to fix view issues.
2022-04-30 08:03:23 +03:00
Arash Khajelou
b68b17c3df Fix the issue with tranlating :number parameter. 2022-04-25 16:33:44 +04:30
Arash Khajelou
218605334c Make some mofigications in rtl style to fix view issues. 2022-04-25 16:30:35 +04:30
FreeScout
8d9f9bead8 Adjust permission name 2022-04-23 23:26:42 -07:00
FreeScout
86e1c292f2 Update French translation 2022-04-23 23:14:21 -07:00
FreeScout
b4c334ed9c Add customer.company variable 2022-04-23 23:07:37 -07:00
FreeScout
3b3c23451b Add customer.company variable to templating #1931 from e1mo/master
Add customer.company variable to templating
2022-04-24 09:03:22 +03:00
FreeScout
8f71f77b1b Merge branch 'master' of github.com:freescout-helpdesk/freescout 2022-04-23 23:01:12 -07:00
FreeScout
84f53fd682 Do not show separator in the plain text email body for the first thread in the loop - closes #1927 2022-04-23 23:00:08 -07:00
FreeScout
a3a27259fc Update readme 2022-04-22 21:56:53 -07:00
Moritz 'e1mo' Fromm
eff6c8c351 Add customer.company variable to templating
A corresponding Feature-Request exists here:
https://feedback.userreport.com/25a3cb5f-e4bd-4470-b6f3-79fcfaa8e90f
2022-04-21 10:36:44 +02:00
FreeScout
2d21c21256 Merge pull request #1923 from RienNeVaPlus/master
Implement actions & filters for an additional user field
2022-04-18 17:18:48 +03:00
RienNeVaPlus
cf01a524e5 Add filter user.setup_save 2022-04-18 01:40:53 +02:00
RienNeVaPlus
51e2f71afc Add filter user.create_save 2022-04-18 01:39:39 +02:00
RienNeVaPlus
358781905f Add action user.setup.before_job_title 2022-04-18 01:38:30 +02:00
RienNeVaPlus
6b782ede62 Add action user.edit.before_email 2022-04-18 01:37:20 +02:00
RienNeVaPlus
425080093b Add action user.create.before_email 2022-04-18 01:36:01 +02:00
FreeScout
415b20020a Add vendor files to dist 2022-04-14 06:13:12 -07:00
FreeScout
29b36472c9 Merge branch 'master' of github.com:freescout-helpdesk/freescout into dist 2022-04-14 06:10:41 -07:00
FreeScout
5f6bd2d993 v1.8.12 2022-04-14 06:09:42 -07:00
FreeScout
8fb6d9152f Trigger phone call when clicking on customer phone - closes #1899 2022-04-14 05:05:07 -07:00
FreeScout
1884048f9c Fix getFullName() on null after deleting a customer - closes #1909 2022-04-14 05:00:10 -07:00
FreeScout
1d859d3fb9 Fix resettings a password on PHP 8.1 - closes #1911 2022-04-14 04:42:48 -07:00
FreeScout
b41e78e71e Merge pull request #1912 from Lars-/master
Multiple filters
2022-04-14 14:25:34 +03:00
FreeScout
e8afbd85a9 Fix clearing Fetching logs - closes #1915 2022-04-14 04:21:54 -07:00
Lars Jansen
d9a8fc8e8b Actions before and after thread recipients 2022-04-12 16:07:12 +02:00
Lars Jansen
a15b65f819 Filter outgoing name 2022-04-12 16:05:16 +02:00
FreeScout
7dc35d143a menu.user.name_append hook 2022-04-06 07:08:00 -07:00
FreeScout
0bdb22e934 Take create_thread parameter into account in changeUser() method 2022-04-06 07:07:28 -07:00
FreeScout
09b777181a Hooks to adjust assignee list 2022-04-06 04:51:31 -07:00
FreeScout
18217c58b6 Hooks to allow adding fields to the user profile 2022-04-06 03:23:51 -07:00
FreeScout
147926bcf1 Add vendor files to dist 2022-04-06 00:03:46 -07:00
FreeScout
3c904fc048 Merge branch 'master' of github.com:freescout-helpdesk/freescout into dist 2022-04-06 00:00:26 -07:00
FreeScout
d1736d9f09 jobs.send_reply_to_customer.headers hook 2022-04-05 23:56:38 -07:00
FreeScout
8ef1fd811b Merge pull request #1882 from DavidAnderson684/patch-3
Add filter allowing customisation of outgoing headers
2022-04-06 09:53:58 +03:00
FreeScout
a64cfa6307 Merge branch 'master' of github.com:freescout-helpdesk/freescout into dist 2022-04-05 23:52:57 -07:00
FreeScout
3f80845371 v1.8.11 2022-04-05 23:52:25 -07:00
FreeScout
80382199ee Fix PHP 8.1 preg_match issue in Mail.php - closes #1888 2022-04-05 22:21:19 -07:00
FreeScout
292e9ec0ae Add noindex meta tag 2022-04-05 22:19:24 -07:00
FreeScout
59b57e268d Fix Passing null to parameter in Kernel.php - closes #1884 2022-04-05 07:25:26 -07:00
FreeScout
153e68f7ae Make symfony/http-foundation/Request.php PHP 8.1 compatible - closes #1841 2022-04-05 07:19:47 -07:00
FreeScout
0b3d36cee0 Allow to translate a message shows after replying - closes #1862 2022-04-05 07:04:38 -07:00
David Anderson
ce2557dd24 Add filter allowing customisation of outgoing headers 2022-04-05 13:52:49 +00:00
FreeScout
a8f5835a39 Merge pull request #1871 from Lars-/master
Add filters to be able to filter SMTP settings when sending a mail
2022-04-05 16:35:16 +03:00
FreeScout
9a273473d5 Fixed undefined variable error on muting notifications #1857 from Jobs-Foundation/master
Fixed undefined variable error on muting notifications
2022-04-05 16:28:23 +03:00
Lars Jansen
25b0c19db1 Add filters to be able to filter SMTP settings when sending a mail 2022-04-02 09:01:45 +02:00
Zachary Schroeder
bbc3e7f3aa fixed undefined variable error 2022-03-29 13:56:13 -05:00
FreeScout
8053591031 Add vendor files to dist 2022-03-29 06:13:20 -07:00
FreeScout
3d2fcd020d Merge branch 'master' of github.com:freescout-helpdesk/freescout into dist 2022-03-29 06:11:56 -07:00
FreeScout
3d7fd68fa8 v1.8.10 2022-03-29 06:11:25 -07:00
FreeScout
1a011d9ea4 Fix Object of class Webklex\PHPIMAP\Header could not be converted to string - closes #1852 2022-03-29 01:18:22 -07:00
FreeScout
57a943edec Fix invalid encoding "default" on PHP 8 - closes #1837 2022-03-29 00:46:37 -07:00
FreeScout
85e9dc53f2 Ensure that there is always a Customer email address when updating a conversation #1847 from edwardhughes/master
Ensure that there is always a Customer email address when updating a conversation
2022-03-29 10:15:16 +03:00
FreeScout
a682d8f7df Add empty string check to hasManageMailboxAccess() #1850 from Jobs-Foundation/master
Add empty string check to hasManageMailboxAccess()
2022-03-29 10:12:47 +03:00
FreeScout
bdc1073a28 Limit user dropdown height in bulk actions - closes #1840 2022-03-29 00:11:32 -07:00
Zachary Schroeder
ac79c57de4 add empty string check 2022-03-28 11:08:36 -05:00
Edward Hughes IV
1b70e45a1c Ensure that there is always a Customer email address when updating a Conversation. 2022-03-25 14:37:54 -04:00
FreeScout
97d0c470fb Fix null to parameter in Swiftmailer - closes #1831 2022-03-20 07:01:08 -07:00
FreeScout
c92589da2a Skip error in setUrl() - closes #1789 2022-03-19 23:32:08 -07:00
FreeScout
3dffd231ae Update FR translation 2022-03-19 23:19:33 -07:00
FreeScout
f429bdef8e Allow PHP 8 in update.sh - closes #1819 2022-03-19 23:14:34 -07:00
FreeScout
11f223ab04 Persian language 2022-03-14 04:18:46 -07:00
FreeScout
2ccf407bd9 RTL adjustments 2022-03-14 00:21:41 -07:00
FreeScout
a172d476f5 Merge pull request #1750 from rhashnull/master
Add RTL and Fa-IR language support for project.
2022-03-14 10:17:22 +03:00
FreeScout
f37303e8a0 Fix recipients names when sending new conversations separately - closes #1802 2022-03-14 00:06:56 -07:00
FreeScout
60016fd532 Show instructions on error 500 page - closes #1808 2022-03-13 06:26:11 -07:00
FreeScout
ab3de1f60b Show Microsoft OAuth connect link only if username is not an email 2022-03-13 01:14:49 -08:00
FreeScout
6014509dd2 Add vendor files to dist 2022-03-13 01:03:57 -08:00
FreeScout
4e856ea783 Merge branch 'master' of github.com:freescout-helpdesk/freescout into dist 2022-03-13 01:01:34 -08:00
FreeScout
23aeefbcbd v1.8.9 2022-03-13 01:01:03 -08:00
FreeScout
b84afb99a5 IMAP oAuth 2022-03-13 00:55:59 -08:00
FreeScout
2dada15292 Merge branch 'oauth2' 2022-03-13 00:54:03 -08:00
FreeScout
a87e2199f0 IMAP oAuth 2022-03-13 00:53:01 -08:00
Arash Khajelou
0e85c73a77 Fix the key name for locales_rtl config. 2022-03-12 15:19:06 +03:30
Arash Khajelou
d7ef54a37e Reverse the format for app.blade.php file. 2022-03-12 15:15:50 +03:30
Arash Khajelou
ed47a5e3c1 Merge branch 'freescout-22-03-12-master' 2022-03-12 15:13:03 +03:30
Arash Khajelou
27698ebea0 Cleanup and add the needed style for rtl locales. 2022-03-12 15:09:40 +03:30
Arash Khajelou
3bcdcd9284 Add locale-{{ app()->getLocale() }} to the body and load Yekan font only for .locale-fa. 2022-03-12 15:09:40 +03:30
Arash Khajelou
640379e4d7 If some language is RTL add dir="rtl" attribute to <html> tag and "rtl" class to the <body> 2022-03-12 15:09:40 +03:30
Arash Khajelou
47b4dfb4b8 Reverse the format of file Helper.php 2022-03-12 15:09:37 +03:30
Arash Khajelou
da2ea1cd1b Add to /app/Misc/Helper.php the isLocaleRtl() method to check if current language is RTL using the config parameter. 2022-03-12 15:08:24 +03:30
Arash Khajelou
12e80d60b6 Add to app.php a list of RTL languages: 'locales_rtl' => ['fa'], 2022-03-12 15:04:14 +03:30
Arash Khajelou
141fd8320e Remove .envrc file 2022-03-12 15:04:14 +03:30
Arash Khajelou
a9ac930cc0 Add persian language support to the project. 2022-03-12 15:04:14 +03:30
Arash Khajelou
344f06178f Cleanup and add the needed style for rtl locales. 2022-03-12 14:55:31 +03:30
Arash Khajelou
0f03f4fffd Add locale-{{ app()->getLocale() }} to the body and load Yekan font only for .locale-fa. 2022-03-12 14:53:44 +03:30
Arash Khajelou
24ef816c2e If some language is RTL add dir="rtl" attribute to <html> tag and "rtl" class to the <body> 2022-03-12 14:51:22 +03:30
Arash Khajelou
516e02be1d Reverse the format of file Helper.php 2022-03-12 14:47:19 +03:30
Arash Khajelou
3c13551a7a Add to /app/Misc/Helper.php the isLocaleRtl() method to check if current language is RTL using the config parameter. 2022-03-12 14:43:50 +03:30
Arash Khajelou
efcf05ad8b Add to app.php a list of RTL languages: 'locales_rtl' => ['fa'], 2022-03-12 14:37:08 +03:30
Arash Khajelou
26b7e1c5c3 Remove .envrc file 2022-03-12 14:31:10 +03:30
FreeScout
2e71180f7c Fix saving System Emails page with empty password on PHP 8.1 2022-03-10 04:02:12 -08:00
FreeScout
a42e0db899 IMAP oAuth - embedded images 2022-03-10 01:26:24 -08:00
FreeScout
3c7dda7118 IMAP oAuth - help link 2022-03-09 06:13:22 -08:00
FreeScout
740d8aa706 IMAP oAuth 2022-03-09 05:24:22 -08:00
FreeScout
e82a1c2b81 IMAP oAuth - refresh access token 2022-03-09 03:45:15 -08:00
FreeScout
7ea7795913 Fix home ulr on 404 - closes #1762 2022-03-09 02:06:24 -08:00
FreeScout
2589aa1da9 IMAP oAuth 2022-03-09 01:10:16 -08:00
FreeScout
18295e83fb Issue template 2022-03-08 22:14:22 -08:00
FreeScout
768c4561a9 IMAP oAuth 2022-03-08 22:13:25 -08:00
FreeScout
dcb7e7715f Merge branch 'master' of github.com:freescout-helpdesk/freescout into dist 2022-03-04 09:22:48 -08:00
FreeScout
767b20f059 v1.8.8 2022-03-04 09:22:23 -08:00
FreeScout
66fba5f20a Take Spread the Word option into accoutn in test mailbox email - #1773 2022-03-04 04:09:13 -08:00
FreeScout
921186e2e0 Fix issue with searching closes #1788 2022-03-04 04:01:15 -08:00
FreeScout
5d41b6908c Issue template 2022-03-04 03:26:47 -08:00
FreeScout
fede8d633a Issue template 2022-03-04 01:19:11 -08:00
FreeScout
182f49f758 IMAP oAuth 2022-03-04 01:13:29 -08:00
FreeScout
91c914fd14 Allow to save fetching settings with empty password on PHP 8.1 2022-02-28 00:57:25 -08:00
FreeScout
c6ea0a85cb Fix PHP 8.1 error when opening fetching settings for a new mailbox 2022-02-28 00:55:18 -08:00
FreeScout
0a6e0a100c Helper currentUrl() 2022-02-26 05:49:39 -08:00
FreeScout
d4b81c4cdb Merge pull request #1768 from Wouter0100/fix/remove-mailbox-cc
Do not add mailbox emails itself to CC on fetching
2022-02-26 08:18:06 +03:00
FreeScout
2b4f67befe Change homepage link on 404 page - closes #1762 2022-02-25 21:11:55 -08:00
Wouter van Os
56597bbd29 fix: do not add mailbox emails itself to CC in new conversation
This fixes a loop that is caused by moving a conversation to
another mailbox. In that case the old mailbox was still visible
as a CC when replying on the moved converstaion. This CC would
result in a new converstation being created.
2022-02-25 17:42:17 +01:00
FreeScout
c0fc874ce4 If custom login page path set do not show login form at /login - closes #1751 2022-02-25 06:25:19 -08:00
FreeScout
d26ab69b18 Fix underscores in encoded subjects 2022-02-22 22:21:01 -08:00
FreeScout
346148ae60 Fix underscores in encoded subjects - closes #1744 2022-02-22 22:10:42 -08:00
FreeScout
8e9bcc6040 Merge branch 'master' of github.com:freescout-helpdesk/freescout into dist 2022-02-22 08:49:20 -08:00
FreeScout
f4c76467bb v1.8.7 2022-02-22 08:48:57 -08:00
FreeScout
26a8d8511f Merge branch 'master' of github.com:freescout-helpdesk/freescout 2022-02-22 02:34:21 -08:00
FreeScout
1873dc6a20 Update modules check 2022-02-22 00:07:20 -08:00
FreeScout
8fa94d8452 Merge pull request #1748 from Lars-/master
Added hooks in preparation for custom signatures module
2022-02-21 09:21:50 +03:00
FreeScout
d62088fa1f Merge pull request #1754 from psuet/patch-1
Add autocomplete Tags to Auth Views
2022-02-21 09:19:27 +03:00
Lars Jansen
03d8e2e0e8 Update update.blade.php 2022-02-20 09:32:44 +01:00
Lars Jansen
4397e0c756 Update editor_bottom_toolbar.blade.php 2022-02-20 09:32:16 +01:00
Lars Jansen
42b23f6e3a Update main.js 2022-02-20 09:31:38 +01:00
Lars Jansen
501b0719cc Update MailboxesController.php 2022-02-20 09:30:39 +01:00
Lars Jansen
1a7289a395 Update ConversationsController.php 2022-02-20 09:30:09 +01:00
Lars Jansen
6153db71c8 Update Conversation.php 2022-02-20 09:29:06 +01:00
Paul Sütterlin
5a7eae76d7 Add autocomplete Tags to Auth Views 2022-02-20 06:21:16 +01:00
Arash Khajelou
cc8e5da17b Add persian language support to the project. 2022-02-19 17:04:24 +03:30
Lars Jansen
54d44ba87a Update editor_bottom_toolbar.blade.php 2022-02-18 15:58:08 +01:00
Lars Jansen
64c46e3941 Update update.blade.php 2022-02-18 15:44:02 +01:00
Lars Jansen
2458539c6f Added hooks in preparation for custom signatures module 2022-02-18 15:31:38 +01:00
FreeScout
c56b9a0573 Merge branch 'master' of github.com:freescout-helpdesk/freescout into dist 2022-02-17 21:51:11 -08:00
FreeScout
eeb00763d3 v1.8.6 2022-02-17 21:50:46 -08:00
FreeScout
800a484acc mail_vars.replace hook 2022-02-16 22:40:25 -08:00
FreeScout
b3e444be47 Merge pull request #1742 from Lars-/master
Mail vars hook
2022-02-17 09:37:41 +03:00
FreeScout
ff025b94d2 Adjust command cron schedule 2022-02-16 22:35:09 -08:00
Lars Jansen
96986e8a22 Allow custom mail vars 2022-02-17 07:25:17 +01:00
FreeScout
2d0c72d5bb PULL_REQUEST_TEMPLATE 2022-02-16 22:11:07 -08:00
FreeScout
384ff40d88 Fix parsing dates with underscores - closes #1738 2022-02-16 04:04:52 -08:00
FreeScout
8dca28adeb Fix preg_match issue in Str.php 2022-02-16 04:04:07 -08:00
FreeScout
1f6a95c4a7 Merge branch 'master' of github.com:freescout-helpdesk/freescout into dist 2022-02-15 05:35:30 -08:00
FreeScout
3493f16035 v1.8.5 2022-02-15 05:34:40 -08:00
FreeScout
97d12be54d Fix command creating modules 2022-02-14 22:11:11 -08:00
FreeScout
19d84bb479 Improve Module::isActive() method performance 2022-02-14 01:11:00 -08:00
FreeScout
2a29e3194e Fix empty parameter passing to strstr() in connection.blade.php 2022-02-13 23:48:54 -08:00
FreeScout
4b8904f335 parseDateToCarbon() helper function 2022-02-13 23:48:35 -08:00
FreeScout
a9d43435e9 Add aria-labels to select2 options 2022-02-13 23:26:12 -08:00
FreeScout
9884a767ff Add aria-labels to summernote buttons 2022-02-13 22:59:48 -08:00
FreeScout
aa1dba6241 Clean summernote folder 2022-02-13 22:38:53 -08:00
FreeScout
ba9293a598 Adjust conversation.can_submit hook 2022-02-08 22:02:47 -08:00
FreeScout
7a15e55da2 Fix null issue in Purifier 2022-02-08 06:34:12 -08:00
FreeScout
77a851cbe0 Do not allow users and mailboxes have the same email addresses 2022-02-08 03:46:23 -08:00
FreeScout
595eaa7a20 Merge branch 'master' of github.com:freescout-helpdesk/freescout into dist 2022-02-07 02:30:35 -08:00
FreeScout
a66b6d019e v1.8.4 2022-02-07 02:30:03 -08:00
FreeScout
b6257aa21c Merge branch 'master' of github.com:freescout-helpdesk/freescout 2022-02-07 02:29:08 -08:00
FreeScout
1a46c7f001 Failed opening required compat/vlucas/phpdotenv/src/Loader.php - closes #1714 2022-02-07 02:29:01 -08:00
FreeScout
8ddbe18543 Merge pull request #1715 from afbora/fix/1713-php8-compatibility
Fix Translation Manager PHP 8 compatibility
2022-02-07 13:11:50 +03:00
Ahmet Bora
5c8de33eb6 Fix php 8 compatibility #1713 2022-02-07 12:03:32 +03:00
FreeScout
7c663cacf8 Add vendor files to dist 2022-02-04 23:53:37 -08:00
FreeScout
1bedf8394d Merge branch 'master' of github.com:freescout-helpdesk/freescout into dist 2022-02-04 23:49:49 -08:00
FreeScout
df0ca8b740 v1.8.3 2022-02-04 23:49:00 -08:00
FreeScout
ced188f286 Flip reply icon - closes #1699 2022-02-04 22:37:31 -08:00
FreeScout
96fa6b5507 Store all vendor overrides in overrides folder 2022-02-04 07:18:23 -08:00
FreeScout
c19600bc7c Store all vendor overrides in overrides folder 2022-02-04 04:18:23 -08:00
FreeScout
cbddefcda2 Add vendor files to dist 2022-02-04 00:26:30 -08:00
FreeScout
a06d2f4c81 Merge branch 'master' of github.com:freescout-helpdesk/freescout into dist 2022-02-04 00:24:16 -08:00
FreeScout
929fc80e66 v1.8.2 2022-02-04 00:24:02 -08:00
FreeScout
56f2f1053b Preserve in vendor exclude-from-classmap files 2022-02-04 00:22:18 -08:00
FreeScout
3f1ec34dea Add vendor files to dist 2022-02-03 23:40:05 -08:00
FreeScout
ddc4f9d452 Merge branch 'master' of github.com:freescout-helpdesk/freescout into dist 2022-02-03 23:36:54 -08:00
FreeScout
14ae10536f v1.8.1 2022-02-03 23:36:16 -08:00
FreeScout
a9a3863d05 Fix ?: operator 2022-02-03 23:30:48 -08:00
FreeScout
9e8ebe17ea PHP 8.1 compatibility 2022-02-03 09:43:12 -08:00
FreeScout
9cca472d29 Add vendor files to dist 2022-02-03 04:03:34 -08:00
FreeScout
44390a6280 Merge branch 'master' of github.com:freescout-helpdesk/freescout into dist 2022-02-03 03:57:32 -08:00
FreeScout
345cdb2702 v1.8.0 2022-02-03 03:57:01 -08:00
FreeScout
a2adf76962 PHP 8.1 compatibility 2022-02-03 03:47:48 -08:00
FreeScout
3d477f6296 Add vendor files to dist 2022-02-02 22:49:30 -08:00
FreeScout
b0469ed5bc Merge branch 'master' of github.com:freescout-helpdesk/freescout into dist 2022-02-02 22:48:17 -08:00
FreeScout
63f5b92a3c PHP 8.1 compatibility 2022-02-02 22:48:10 -08:00
FreeScout
a5d03df940 Merge branch 'master' of github.com:freescout-helpdesk/freescout into dist 2022-02-02 22:26:06 -08:00
FreeScout
2b07bcbca7 PHP 8.1 compatibility - closes #1691 2022-02-02 22:25:12 -08:00
FreeScout
d55bfd6495 Optimize search query 2022-01-31 21:35:39 -08:00
FreeScout
8210891675 Fix redirecting to root in subdirectory 2022-01-31 21:35:18 -08:00
FreeScout
beeeadf34a Merge pull request #1689 from GaneshKandu/patch-2
Fix redirecting to root in subdirectory
2022-02-01 08:30:35 +03:00
Ganesh Kandu
1f8b2098cc Freescout 1.7.30 redirecting to root
#1668 
This can be solution of this issue

if ```APP_DASHBOARD_PATH``` is empty it will redirect to ```/``` only
2022-01-31 14:26:38 +05:30
FreeScout
669ebf79e1 Optimize search query 2022-01-31 00:29:24 -08:00
FreeScout
8a0077c94d Fix search navigation with complex search filters 2022-01-31 00:08:43 -08:00
FreeScout
a2910deed3 Fix customer conversations pagination 2022-01-30 23:37:47 -08:00
FreeScout
039623097d Conversation::search() function 2022-01-30 05:43:18 -08:00
FreeScout
833158b0de Light color for spam conversations - closes #1680 2022-01-29 06:13:58 -08:00
FreeScout
d1598d61ac Add Collision detection to Readme 2022-01-29 05:57:28 -08:00
FreeScout
672149d3f7 Check if mailbox exists in SendReplyToCustomer job - closes #1678 2022-01-29 05:53:59 -08:00
FreeScout
5db4c5ced2 Show merged conversation link in the notice - closes #1686 2022-01-29 05:50:32 -08:00
FreeScout
8f07621946 Remove MS SQL from installation wizard - closes #1685 2022-01-29 02:04:32 -08:00
FreeScout
3235e60f72 Set all required parameters in Conversation::create() to avoid PostgreSQL error 2022-01-25 22:23:02 -08:00
FreeScout
566640d287 Set default options in \Helper::htmlToText() no to split the text 2022-01-24 22:58:33 -08:00
FreeScout
c10686e546 Fix customers search on PostgreSQL - closes #1664 2022-01-24 09:37:50 -08:00
FreeScout
fb1ac61d64 Merge branch 'master' of github.com:freescout-helpdesk/freescout into dist 2022-01-24 01:14:00 -08:00
FreeScout
813bc84575 v1.7.30 2022-01-24 01:12:58 -08:00
FreeScout
323e9d7a20 Merge branch 'master' of github.com:freescout-helpdesk/freescout into dist 2022-01-23 22:44:39 -08:00
FreeScout
f134a0288e v1.7.29 2022-01-23 22:43:21 -08:00
FreeScout
7324f15c50 Fix sorting conversations - closes #1662 2022-01-23 22:39:38 -08:00
FreeScout
b8286e7875 Clear note from cache after sending it - closes #1434 2022-01-22 22:09:05 -08:00
FreeScout
1afb66ce0b Merge branch 'master' of github.com:freescout-helpdesk/freescout into dist 2022-01-22 01:24:55 -08:00
FreeScout
ec4670757e v1.7.28 2022-01-22 01:24:20 -08:00
FreeScout
92a9e7cb78 Helper isPgSql() function 2022-01-22 01:21:51 -08:00
FreeScout
dd8e8274a1 Improve sorting convesations table 2022-01-21 23:53:12 -08:00
FreeScout
b010996391 Merge pull request #1651 from alinmbb/master
Sorting conversations by columns
2022-01-22 09:07:46 +03:00
FreeScout
5bbe2b9d73 search.conversations_tab_append hook 2022-01-21 08:24:03 -08:00
FreeScout
c2336d9ca8 Fix Call to a member function isDraft() on null in SendNotificationToUsers - closes #1649 2022-01-21 06:48:01 -08:00
FreeScout
1b29571ba9 Add Integromat to Readme 2022-01-20 07:31:58 -08:00
mbb
810d2e3924 Added Conversations sorting by subject, Number, Creation Date in Mailbox view page 2022-01-20 09:23:44 +00:00
FreeScout
55d24994df search.conversations_tab_append hook 2022-01-15 06:31:48 -08:00
FreeScout
f0bba4b77b .fs-trigger-modal class to trigger modals 2022-01-15 06:31:28 -08:00
FreeScout
eefc7fd153 Allow to customize login path 2022-01-14 06:27:45 -08:00
FreeScout
f24b2e5040 Merge pull request #1628 from searsaw/pass-htmltotext-config
Add ability to pass config to Html2Text
2022-01-08 07:55:02 +03:00
Alex Sears
d96c180631 Add ability to pass config to Html2Text 2022-01-07 15:53:09 -05:00
FreeScout
f78933e2a4 Merge pull request #1623 from TylerB260/master
convsersation -> conversation Typo Fix
2022-01-06 08:20:36 +03:00
Tyler R. Bundy
b30b996e9c convsersation -> conversation 2022-01-05 13:14:21 -06:00
FreeScout
a51cb49225 Redirect to /home after login 2022-01-05 04:54:53 -08:00
FreeScout
f4924c3140 Merge branch 'master' of github.com:freescout-helpdesk/freescout into dist 2022-01-05 02:36:04 -08:00
FreeScout
c1b08383ef v1.7.27 2022-01-05 02:35:37 -08:00
FreeScout
59651ee24d guest_mode and no_footer options in the layout template 2022-01-05 00:21:05 -08:00
FreeScout
11b79b2b48 Add dashboard_path and home_controller to config 2022-01-04 23:52:53 -08:00
FreeScout
ac03db6380 menu.mailboxes hook 2022-01-04 01:31:36 -08:00
FreeScout
5d590d598e Always cache mailboxes in menu 2022-01-04 01:17:43 -08:00
FreeScout
17a157eb60 Merge branch 'master' of github.com:freescout-helpdesk/freescout into dist 2021-12-31 04:16:16 -08:00
FreeScout
2446a94d50 v1.7.26 2021-12-31 04:15:47 -08:00
FreeScout
53240b6360 deleteAttachments() function 2021-12-31 04:10:14 -08:00
FreeScout
b4b09213f7 Allow to pass user or user_id to Mailbox userHasAccess() 2021-12-31 04:00:36 -08:00
FreeScout
cdf6fd07cf thread.attachment_append hook 2021-12-31 01:08:12 -08:00
FreeScout
a0c5748c59 Merge pull request #1593 from Wouter0100/feature/add-fetching-email-hooks
Added hooks for custom fetching
2021-12-29 11:03:20 +03:00
Wouter van Os
d599c63816 Implemented @action in connection_incoming instead of foreach 2021-12-28 19:57:23 +01:00
FreeScout
c4fb834cd0 Allow to pass plain list of emails to Customer setData() 2021-12-28 06:59:24 -08:00
FreeScout
f605cf7e85 Allow to pass plain list of emails to Customer setData() 2021-12-28 06:38:38 -08:00
FreeScout
fa06b7148e Expand customer address block if non-empty 2021-12-28 05:51:13 -08:00
FreeScout
f17755aad8 Sanitize country in cusmer setData() 2021-12-28 05:49:05 -08:00
Wouter van Os
e4fdab0a19 Implemented feedback for implementing custom fetch providers
- Defaulting settings to visible
- Only add WHERE clause when not in_protocols is not empty
- Add tested arg to fetch_test
2021-12-27 18:01:45 +01:00
FreeScout
94af31c686 Merge branch 'master' of github.com:freescout-helpdesk/freescout into dist 2021-12-25 22:02:18 -08:00
FreeScout
28902b4c9f v1.7.25 2021-12-25 22:01:32 -08:00
FreeScout
e57ed73f98 Send attachments to all emails when sending to multiple recepients - closes #1599 2021-12-25 06:26:34 -08:00
FreeScout
bf1eb5985a Remove limitation on user Alternate Emails max length - closes #1592 2021-12-25 06:08:54 -08:00
FreeScout
2188ce8a4e Helper::setLocale() function 2021-12-24 23:41:13 -08:00
Wouter van Os
33767a590a Added hooks for custom fetch email providers 2021-12-23 23:19:19 +01:00
FreeScout
352469b662 Fix logs names in Logs 2021-12-15 22:42:54 -08:00
FreeScout
01b8da7cc2 conversations_table.before_mailbox hook 2021-12-13 09:26:42 -08:00
FreeScout
f9b517c849 Merge branch 'master' of github.com:freescout-helpdesk/freescout into dist 2021-12-13 06:41:47 -08:00
FreeScout
962418a9ee v1.7.24 2021-12-13 06:41:28 -08:00
FreeScout
3353d57c84 Merge pull request #1578 from philippkraft/master
Improve accessibility of modal dialogs (#1150)
2021-12-12 13:13:38 +03:00
FreeScout
0ed7db3b0c Fix last reply date for phone conversations 2021-12-09 22:44:26 -08:00
FreeScout
5ad58e5b25 conversations_table.before_mailbox hook 2021-12-09 01:17:12 -08:00
FreeScout
e28f174f20 Adjust default subscription implementation 2021-12-08 22:28:03 -08:00
FreeScout
4a8aae7aff Implement configuration for default subscriptions (fixes #294) 2021-12-09 08:28:59 +03:00
Philipp Kraft
e780a863cf Improve accessibility of modal dialogs (#1150)
Change aria-hidden attribute to aria-modal attribute to make modal dialogs accessible for screen readers
2021-12-08 20:35:55 +01:00
Moritz Marquardt
86c2724ceb Fix formatting (tabs vs. spaces) 2021-12-08 15:16:22 +01:00
Moritz Marquardt
6677cf39a9 Fix accessibility & translation issues and add German translation for default subscriptions 2021-12-08 15:01:44 +01:00
Moritz Marquardt
0bac1ae3c4 Make default subscription settings persistent 2021-12-08 14:51:02 +01:00
Moritz Marquardt
a152d8bf06 Add UI for subscriptions defaults 2021-12-08 14:39:04 +01:00
FreeScout
badba682a0 .dropdown-menu.with-icons style 2021-12-08 01:09:13 -08:00
FreeScout
90ae9e2a7e Conversations::create() should create phone conversations in Pending status 2021-12-06 22:42:34 -08:00
FreeScout
69cbede2f4 Clarify in comment why customer changes when CCed recipient replies 2021-12-05 21:56:07 -08:00
FreeScout
754c3d7e75 Merge pull request #1575 from Wouter0100/patch-2
Fix Thread type being changed in ThreadObserver
2021-12-06 08:34:04 +03:00
Wouter van Os
3814a2d3e9 Fix issue of Thread type being incorrect after save
This caused all kinds of weird behaviours, where one of them was #1574. This fixes it.
2021-12-05 21:16:20 +01:00
FreeScout
97fb5678bc Merge branch 'master' of github.com:freescout-helpdesk/freescout into dist 2021-12-03 04:58:12 -08:00
FreeScout
964249c1d4 v1.7.23 2021-12-03 04:57:52 -08:00
FreeScout
607ae55db7 Fix issue with chat convesations being converted into regular conversations - closes #1565, #1568 2021-12-03 04:57:11 -08:00
FreeScout
b7dae29b5f Properly process attachments with slashes - closes #1566 2021-12-03 04:44:40 -08:00
FreeScout
87d48a3428 Fix Trying to get property id of non-object in SendNotificationToUsers.php - closes #1557 2021-12-03 04:38:52 -08:00
FreeScout
82a8876209 replaceAll() JS function 2021-12-02 21:57:00 -08:00
FreeScout
325ad1914b .panel-sortable-input style 2021-12-02 21:56:40 -08:00
FreeScout
d1bcef4df7 Update rollback for remove_unique_index_in_folders_table 2021-12-01 06:08:21 -08:00
FreeScout
7c0ef24bfd loadMailboxes() for convesations and checking status in changeStatus() 2021-12-01 04:12:11 -08:00
Moritz Marquardt
038c3610ac Implement configuration file for default subscriptions (fixes #294) 2021-11-30 19:11:02 +01:00
FreeScout
62ea562f26 Merge branch 'master' of github.com:freescout-helpdesk/freescout into dist 2021-11-30 04:12:54 -08:00
FreeScout
3f17e9b811 v1.7.22 2021-11-30 04:12:30 -08:00
FreeScout
c08c077b8f Properly save attachments without a name - closes #1548 2021-11-30 04:02:51 -08:00
FreeScout
b5efc28b0f Set data-customer_id on customer conversation page to fix deleting customer 2021-11-30 03:37:01 -08:00
FreeScout
ab55a5fe19 Allow multiple personal folders for users - closes #843 2021-11-30 00:57:05 -08:00
FreeScout
f5e493e5dc Fix empty customer when creating a phone conversation without saving it as a draft first 2021-11-29 23:03:51 -08:00
FreeScout
e6ab5eba07 Fix (no subject) issue when creating a new conversation and sending it quickly 2021-11-29 22:45:45 -08:00
FreeScout
d0f1b621fe Fix creating a phone conversation without saving it first as draft 2021-11-29 22:42:33 -08:00
FreeScout
79aca06be8 Allow to get via phone conversation last reply via getLastReply() 2021-11-29 22:42:10 -08:00
FreeScout
9e7f2e22dd Add html_tag parameter to initModals() function 2021-11-29 00:38:23 -08:00
FreeScout
d11c9c83f0 glyphicon-spin 2021-11-19 07:06:59 -08:00
FreeScout
9e0622f91f .footer-hide class 2021-11-17 03:33:47 -08:00
FreeScout
ea7e30b9cc Disable authentication for cron URL - closes #1545 2021-11-17 03:33:33 -08:00
FreeScout
9c52ea8eca Add badges partial 2021-11-17 00:24:05 -08:00
FreeScout
79db2920ca Merge branch 'master' of github.com:freescout-helpdesk/freescout into dist 2021-11-14 23:13:11 -08:00
FreeScout
df9370a37f v1.7.21 2021-11-14 23:12:55 -08:00
FreeScout
416d07fcce Heading styles 2021-11-14 23:12:30 -08:00
FreeScout
5384a32d58 Set last reply date for phone conversations 2021-11-09 09:28:12 -08:00
FreeScout
18e9679553 Adjust .main-heading style 2021-11-09 08:46:29 -08:00
FreeScout
c0cef1b178 Slovak language added 2021-11-08 03:34:06 -08:00
FreeScout
045c1833e3 Update French translations 2021-11-08 03:30:49 -08:00
FreeScout
d4f8134de4 Update Croatian translations 2021-11-08 03:27:27 -08:00
FreeScout
78596eb4c9 Merge pull request #1528 from andrewlimaza/master
Add support to get module image from modules.json
2021-11-01 16:50:49 +03:00
Andrew Lima
380a275248 Add support to get module image from modules.json
Add support for module.json 'img' attribute. Use this to set a path to the image for your custom module icon/logo.
2021-11-01 14:23:53 +02:00
FreeScout
a0b98cabf1 Fix duplicated customers in the Search - closes #1521 2021-10-29 07:17:51 -07:00
FreeScout
2ccc6dd141 Disable sql_require_primary_key=0 for PostgreSQL - closes #1518 2021-10-28 05:51:19 -07:00
FreeScout
a52336dc01 Fix notifications dropdown height on screen with height > 1086px - closes #1517 2021-10-28 05:37:01 -07:00
FreeScout
d70ae69dae Correct photo size in user profile 2021-10-28 05:25:41 -07:00
FreeScout
5eeed269b6 Merge branch 'master' of github.com:freescout-helpdesk/freescout into dist 2021-10-21 05:54:00 -07:00
FreeScout
eedc9e8f94 v1.7.20 2021-10-21 05:53:42 -07:00
FreeScout
950af7b268 Add Croatian language 2021-10-21 05:50:53 -07:00
FreeScout
5f9e02012a Access user in created_by_user_id in Thread::createExtended() 2021-10-21 05:40:57 -07:00
FreeScout
548517b906 Merge branch 'master' of github.com:freescout-helpdesk/freescout 2021-10-21 00:54:21 -07:00
FreeScout
c29f902483 Fix auto refreshing conversation by new user message - closes #1405 2021-10-21 00:53:44 -07:00
FreeScout
46919ba5a3 Merge pull request #1500 from alinmbb/master
Add side layout hook on the New Conversation page
2021-10-20 18:01:48 +03:00
FreeScout
c4a4f33633 Merge branch 'master' of github.com:freescout-helpdesk/freescout into dist 2021-10-20 07:45:16 -07:00
FreeScout
5176f0456f v1.7.19 2021-10-20 07:44:54 -07:00
alinmbb
fb3e2635f5 Update create.blade.php
Updated hook name
2021-10-20 13:38:49 +02:00
alinmbb
380d1269d0 Update create.blade.php
Added side layout hook on the New Conversation page
2021-10-20 13:33:05 +02:00
FreeScout
069e82c097 users.email filter 2021-10-20 04:26:54 -07:00
FreeScout
9a836a01fd Add password reset throttling 2021-10-20 00:27:07 -07:00
FreeScout
eaffa01452 Add community modules link to the readme 2021-10-19 23:43:45 -07:00
FreeScout
169fa21966 Add cloud hosted link to readme 2021-10-19 23:41:13 -07:00
FreeScout
20e0dae7a3 Add cloud hosted link to readme 2021-10-19 23:39:33 -07:00
FreeScout
358db187be If conversation from deleted customer arrives the customer is empty 2021-10-16 00:50:38 -07:00
FreeScout
fe17e3c4bb Merge pull request #1491 from laurentenhoor/feature/minimal-ui-changes-with-maximal-impact
Set min dashboard card header height
2021-10-16 10:38:35 +03:00
FreeScout
60e0d3c40c Check customer existence in thread tempalte 2021-10-15 23:55:15 -07:00
FreeScout
1753a6f654 customer.edit.before_form hook 2021-10-15 23:54:57 -07:00
FreeScout
d41e0e6c8c Fix protocol in search tabs 2021-10-15 23:54:21 -07:00
FreeScout
6f09d91a50 closeAllModals() JS function 2021-10-15 10:59:44 -07:00
FreeScout
75c6008acc Fix error in SendNotificationToUsers.php when deleting customers 2021-10-15 10:59:32 -07:00
Lauren ten Hoor
7c581cc7bb Another fix for additional dashboard items. 2021-10-15 12:05:50 +01:00
FreeScout
0715f008ca Merge pull request #1490 from laurentenhoor/feature/minimal-ui-changes-with-maximal-impact
Minor UI updated for more professional look and feel.
2021-10-15 12:29:09 +03:00
Lauren ten Hoor
61f4c3760b Minor UI updated for more professional look and feel. 2021-10-15 10:18:50 +01:00
FreeScout
ad1a464335 Add customer menu 2021-10-15 01:16:03 -07:00
FreeScout
76ca9a1153 Merge pull request #1486 from laurentenhoor/bugfix/unable-to-run-isDraft()-on-null
Fixing error about: "unable to run isDraft() on null".
2021-10-15 09:42:08 +03:00
Lauren ten Hoor
461a786ebc Fixing error about: "unable to run isDraft() on null". 2021-10-14 13:38:03 +01:00
FreeScout
170c282f3e Merge branch 'master' of github.com:freescout-helpdesk/freescout into dist 2021-10-14 03:26:29 -07:00
FreeScout
c7480c81b2 v1.7.18 2021-10-14 03:26:11 -07:00
FreeScout
de62a0c11b Add .eml extension to RFC822 attachments - closes #986 2021-10-13 11:04:30 -07:00
FreeScout
dc35f63586 Fix reopening a conversation when customer replies from chat - closes #1461 2021-10-13 07:31:46 -07:00
FreeScout
f5d7808792 Fix reopening a conversation when customer replies from chat - closes #1461 2021-10-13 01:51:49 -07:00
FreeScout
1bf03b619a Undelete deleted conversation when customer replies via chat or API - closes #1468 2021-10-13 00:55:20 -07:00
FreeScout
e109f5782c Add Danish language 2021-10-12 23:24:02 -07:00
FreeScout
3c57cf0f65 Fix users_to_notify must be an array 2021-10-06 11:05:54 -07:00
FreeScout
475917c110 Log error when app can not fetch message from mail server in Show Original window - closes #1446 2021-10-04 23:22:02 -07:00
FreeScout
3b7ece1790 Web cron - closes #1452 2021-10-04 04:54:02 -07:00
FreeScout
2a6c5faa79 Merge branch 'master' of github.com:freescout-helpdesk/freescout into dist 2021-09-23 03:06:15 -07:00
FreeScout
7446cce387 v1.7.17 2021-09-23 03:05:59 -07:00
FreeScout
15bb477e84 thread.menu.append hook 2021-09-22 05:28:33 -07:00
FreeScout
83071f3a1d Allow to skip user time zone in dateFormat() function 2021-09-22 05:27:32 -07:00
FreeScout
eb579823db Add indexes to Conversations table - closes #1425 2021-09-21 03:12:54 -07:00
FreeScout
fe702bcaea Fix Undefined constant STDIN on module activation - closes #1423 2021-09-21 01:15:44 -07:00
FreeScout
0d87a6ea93 Fix Call to a member function getFullName in web_notifications partial - closes #1410 2021-09-21 00:19:26 -07:00
FreeScout
d9135c134b Update Russian translation 2021-09-21 00:13:13 -07:00
FreeScout
eb33b0c3c7 Update Polish translation 2021-09-21 00:12:15 -07:00
FreeScout
93471f4342 Update German translation 2021-09-21 00:11:00 -07:00
FreeScout
0db0bfdfd4 Improve security of Translate page 2021-08-29 01:47:05 -07:00
FreeScout
92e4dbcaa8 Add SESSION_SECURE_COOKIE to web installer 2021-08-29 00:53:24 -07:00
FreeScout
15443d155b Add SESSION_SECURE_COOKIE to .env.example 2021-08-29 00:50:05 -07:00
FreeScout
21283962c4 Add SECURITY.md 2021-08-29 00:08:39 -07:00
FreeScout
1816aa2761 Merge branch 'master' of github.com:freescout-helpdesk/freescout into dist 2021-08-25 05:53:54 -07:00
FreeScout
3d862b03eb v1.7.16 2021-08-25 05:53:36 -07:00
FreeScout
411fca2ab3 Fix page generation error with multiple agents 2021-08-25 05:24:27 -07:00
FreeScout
8190907e39 Merge pull request #1396 from ejhayter/ejhayter-patch-2
Fix page generation error with multiple agents
2021-08-25 15:05:47 +03:00
Emily Hayter
05fbc0b80d Fix page generation error with multiple agents
When multiple agents were viewing an email, the following error was seen:

usort(): Returning bool from comparison function is deprecated, return
    an integer less than, equal to, or greater than zero at
    /www/html/app/Http/Controllers/ConversationsController.php:252

Opted for spaceship operator, I was not able to verify that the code is
operating as intended, only that it resolved the generated error.
2021-08-25 12:33:29 +01:00
FreeScout
347397f4da Help info for Alternate Emails field 2021-08-20 00:41:44 -07:00
FreeScout
1d0e37950d Allow users to reply from Alternate emails - closes #1363 2021-08-19 07:12:47 -07:00
FreeScout
7828df20fc Add vendor files to dist 2021-08-10 22:19:57 -07:00
FreeScout
a72f6b964f Merge branch 'master' of github.com:freescout-helpdesk/freescout into dist 2021-08-10 22:18:39 -07:00
FreeScout
950dc05843 v1.7.15 2021-08-10 22:18:18 -07:00
FreeScout
6a242635f7 fzaninotto/faker v1.9.2 2021-08-10 22:14:53 -07:00
FreeScout
dff1bd0d40 Merge pull request #1364 from admdly/fix-faker-php74
Update fzaninotto/faker to fix PHP >= 7.4 compatibility
2021-08-11 08:13:31 +03:00
Adam
d678390b17 Bump fzaninotto/faker to fix PHP >= 7.4 compatibility
Update fzaninotto/faker to fix issue due to changes with implode() in PHP >= 7.4 (see fzaninotto/faker#1748).
2021-08-10 06:06:54 +01:00
FreeScout
579b0bc5ef Fix saving multiple recipients in a new conversation draft 2021-08-06 23:31:07 -07:00
FreeScout
23b01416d7 Fix short text in the menu notification 2021-08-06 07:18:05 -07:00
FreeScout
3266b33b05 Make SVG attachments non-viewable to avoid XSS - closes #1359 2021-08-06 03:12:51 -07:00
FreeScout
ad686553e5 Allow modules to show menu notifications 2021-08-05 23:45:57 -07:00
FreeScout
e289f5acbd Fix short text in the menu notification 2021-08-05 07:05:36 -07:00
FreeScout
1573f73a0e Extend thread description text compilation 2021-08-05 06:52:28 -07:00
FreeScout
efcac585ef Fix summernote click on HintPopover suggestions doesnt insert 2021-08-05 03:34:44 -07:00
FreeScout
89757bc7dd Subscription hooks 2021-08-05 03:25:12 -07:00
FreeScout
04e8391ca2 editor.options hook 2021-08-04 23:47:27 -07:00
FreeScout
7f6bda6c76 Add vendor files to dist 2021-08-03 07:47:45 -07:00
FreeScout
b3b5063b50 Merge branch 'master' of github.com:freescout-helpdesk/freescout into dist 2021-08-03 07:45:49 -07:00
FreeScout
a79d9aa094 v1.7.14 2021-08-03 07:45:35 -07:00
FreeScout
b8f3200f8f Fix htmlpurifier INTL_IDNA_VARIANT_2003 issue on PHP7.2 and 7.3 - closes #1322 2021-08-03 07:30:57 -07:00
FreeScout
b702566cb0 Fix mobile notifications link 2021-08-03 06:26:39 -07:00
FreeScout
69b4d0a322 Fix starred folder position 2021-08-01 04:12:27 -07:00
FreeScout
b2d17e3639 Highlight folders counters 2021-07-31 11:02:15 -07:00
FreeScout
29ef585c31 Folders hooks 2021-07-31 11:00:55 -07:00
FreeScout
d3d1c4ccb9 Highlight folders counters 2021-07-31 05:51:00 -07:00
FreeScout
f53a260dff Add arrow showing conversations sorting column - closes #919 2021-07-30 23:16:19 -07:00
FreeScout
e8e86d1bf4 email.auto_reply.subject hook 2021-07-28 22:49:36 -07:00
FreeScout
284d8f07fa Fix in_array expects parameter 2 to be array in BroadcastNotification 2021-07-28 21:00:57 -07:00
FreeScout
aca1d26a76 Properly restore Cc and Bcc from draft 2021-07-18 05:01:29 -07:00
FreeScout
3ef5c28bac Merge branch 'master' of github.com:freescout-helpdesk/freescout into dist 2021-07-18 01:37:49 -07:00
FreeScout
de5c9f6047 v1.7.13 2021-07-18 01:37:27 -07:00
FreeScout
b4b93af96a Make users unique in the Assigned search filter - closes #1326 2021-07-17 22:30:59 -07:00
FreeScout
9d52e8853e Conversation recipient selector hooks 2021-07-12 00:22:48 -07:00
FreeScout
2369c9b3be v1.7.12 2021-07-10 22:37:56 -07:00
FreeScout
8ee0699b3e v1.7.12 2021-07-10 22:35:58 -07:00
FreeScout
fcb18e56f0 v1.7.12 2021-07-10 22:32:19 -07:00
FreeScout
14bbab0969 Merge pull request #1319 from fulldecent/patch-5
Add supported versions of PHP
2021-07-11 08:30:23 +03:00
William Entriken
d84fe65460 Add supported versions of PHP 2021-07-09 14:51:48 -04:00
FreeScout
047b8d1433 Merge pull request #1308 from henrikhj/patch-1
Fix tracking pixel in PHP 8
2021-07-07 09:39:32 +03:00
FreeScout
6e699a27ab Merge pull request #1310 from fulldecent/patch-4
Add button role for conversation actions
2021-07-07 09:36:38 +03:00
William Entriken
fd45d20876 Extend aria-labels 2021-07-06 16:16:56 -04:00
William Entriken
f977ff30ea More role and aria label 2021-07-06 16:16:56 -04:00
William Entriken
27946aabae aria-label for dropdowns 2021-07-06 16:16:56 -04:00
William Entriken
acdc935f70 Add aria-label 2021-07-06 16:16:53 -04:00
William Entriken
28cd928a1b Add role buttons 2021-07-06 16:16:44 -04:00
Henrik Jensen
405f09ff00 Fixes #1252
Fixes #1252 "Missing format specifier at end of string" in sprintf due to mismatched number of % and format specifiers.
2021-07-05 15:16:04 +02:00
FreeScout
9c1ac14bf1 Fix duplicating attachments when creating a new conversation 2021-07-03 04:28:58 -07:00
FreeScout
920afd6045 Add Telegram to customer social profiles list 2021-07-03 03:00:54 -07:00
FreeScout
60912da17c Add mailbox name to the title - closes #1297 2021-07-02 23:13:40 -07:00
FreeScout
68eff16f64 Merge pull request #1284 from fulldecent/patch-3
Create FUNDING.yml
2021-07-03 08:12:56 +03:00
William Entriken
475eb0565d Add funding option, fixes #1279 2021-06-24 14:27:57 -04:00
FreeScout
cc58b6739b Merge branch 'master' of github.com:freescout-helpdesk/freescout into dist 2021-06-23 07:32:51 -07:00
FreeScout
3f66a76727 v1.7.11 2021-06-23 07:32:42 -07:00
FreeScout
deaec751b0 Merge branch 'master' of github.com:freescout-helpdesk/freescout into dist 2021-06-23 07:31:32 -07:00
FreeScout
baff0ab7e4 Fix Array to string converstion error when creating a custommer - closes #1282 2021-06-23 07:28:52 -07:00
FreeScout
45a56f6ca3 Empty alt for logo image 2021-06-22 23:30:30 -07:00
FreeScout
8a14756cea Merge pull request #1278 from fulldecent/patch-1
Fix HTML warning by adding alt to the logo image
2021-06-23 09:28:55 +03:00
FreeScout
c39b0f1e02 Return hyphen to the footer 2021-06-22 23:27:46 -07:00
FreeScout
27d8706023 Merge pull request #1280 from fulldecent/patch-2
Update numeric range dash
2021-06-23 09:24:50 +03:00
FreeScout
ef434e5491 Updated Japanese translations 2021-06-22 23:24:16 -07:00
FreeScout
88c960dfad Italian translation 2021-06-22 23:22:48 -07:00
William Entriken
d028dee724 Update app.blade.php 2021-06-22 11:25:27 -04:00
William Entriken
d17a9e2ef1 Fix HTML warning 2021-06-22 10:23:17 -04:00
FreeScout
85399792fb email.reply_to_customer.subject hook 2021-06-17 00:51:44 -07:00
FreeScout
a02ed17233 Replace calendar partial with include_datepicker 2021-06-16 23:00:31 -07:00
FreeScout
3dc5f1c843 Replace calendar partial with include_datepicker 2021-06-16 10:04:36 -07:00
FreeScout
2a077ecf81 Merge branch 'master' of github.com:freescout-helpdesk/freescout into dist 2021-06-16 05:06:41 -07:00
FreeScout
1ae5fe8cc3 v1.7.10 2021-06-16 05:05:06 -07:00
FreeScout
658ac6b759 Disable updated_at field in Job 2021-06-15 05:18:24 -07:00
FreeScout
08973f9b50 email_notification.before_body hook 2021-06-15 01:49:15 -07:00
FreeScout
1abd3e2aa7 Thread unset meta function 2021-06-15 01:48:43 -07:00
FreeScout
49929dd4a0 Delay hooks 2021-06-15 01:48:28 -07:00
FreeScout
15cce31886 Adjust alerts within thread body 2021-06-11 02:00:32 -07:00
FreeScout
0302556635 thread.before_save_from_request hook 2021-06-11 02:00:17 -07:00
FreeScout
1ae8ff4b99 Init modals after adding editor bottom tollbar to HTML 2021-06-10 06:54:33 -07:00
FreeScout
ca75a702ca conversation.append_send_dropdown hook 2021-06-10 06:54:03 -07:00
FreeScout
14096aeaf8 Fix customer sidebar height with JS 2021-06-10 02:09:23 -07:00
FreeScout
b9ebef7817 Fix customer sidebar height with JS 2021-06-10 01:46:33 -07:00
FreeScout
b4f6f8f2d0 Update PL translation 2021-06-09 01:44:32 -07:00
FreeScout
d27b2f9727 Copy customer email on clicking on it 2021-06-05 03:49:15 -07:00
FreeScout
fd0e58e957 Merge pull request #1248 from foliovision/fix-email-customer-link
Open New Conversation by clicking on customer email
2021-06-05 13:34:48 +03:00
Alec Kinnear
eaf08c60d4 Fixing missing Email Customer link in sidebar
Realized same template is used also for the customer view, where $mailbox cannot be used
2021-06-04 15:24:08 +02:00
Alec Kinnear
6e900d111c Fixing missing Email Customer link in sidebar
Found proper function
2021-06-04 13:55:36 +02:00
Alec Kinnear
cf6a192ccc Fixing missing Email Customer link in sidebar 2021-06-04 13:46:18 +02:00
FreeScout
515a8d2b54 Remove office hours notice from mailbox auto reply page 2021-05-21 22:14:59 -07:00
FreeScout
4018604028 Merge branch 'master' of github.com:freescout-helpdesk/freescout into dist 2021-05-21 07:55:19 -07:00
FreeScout
55d70f8454 Fix encrypting mailbox password migration 2021-05-21 07:54:45 -07:00
FreeScout
fd08b5d4ee v1.7.9 2021-05-21 07:42:05 -07:00
FreeScout
f7cd18d4ad Fix mailbox password encyption migration 2021-05-21 07:41:39 -07:00
FreeScout
078e098b28 Merge branch 'master' of github.com:freescout-helpdesk/freescout into dist 2021-05-21 05:55:25 -07:00
FreeScout
b2f761ef76 1.7.8 2021-05-21 05:54:48 -07:00
FreeScout
cdd894b50c Improve encrypting mail password 2021-05-21 05:54:02 -07:00
FreeScout
323524ac1b Merge pull request #1227 from davask/encrypt_mail_password
encrypt mail password
2021-05-21 15:35:29 +03:00
FreeScout
bc04ca3db7 Improve encrypting out password 2021-05-21 05:32:08 -07:00
FreeScout
434d2c76e0 Merge branch 'master' of github.com:freescout-helpdesk/freescout 2021-05-21 05:28:34 -07:00
FreeScout
009aecc72a Merge pull request #1226 from davask/encrypt_out_password
Encrypt out_password
2021-05-21 15:27:47 +03:00
davask
ddd7885038 encrypt mail password 2021-05-21 12:21:54 +02:00
FreeScout
a46a7f5429 autoreply.should_send 2021-05-21 01:51:11 -07:00
davask
fe5e7011cc Encrypt out_password 2021-05-21 10:22:57 +02:00
FreeScout
e12da9e82d Properly update folders when moving conversation - closes #1210 2021-05-20 02:09:12 -07:00
FreeScout
dddf4d12df Add vendor files to dist 2021-05-18 23:27:40 -07:00
FreeScout
96033cbc78 Merge branch 'master' of github.com:freescout-helpdesk/freescout into dist 2021-05-18 23:26:08 -07:00
FreeScout
b821d3fd09 v1.7.7 2021-05-18 23:25:19 -07:00
FreeScout
1b6dcb00e7 mailbox.url hook 2021-05-18 08:03:49 -07:00
FreeScout
938e4e1ad7 folder.url hook 2021-05-18 07:44:31 -07:00
FreeScout
cd99b04507 conversations.ajax_pagination_folder hook 2021-05-18 06:36:55 -07:00
FreeScout
ba49cde9f6 folder.active_count_mine_folder hook 2021-05-18 06:35:41 -07:00
FreeScout
3f82e25074 Cache starred conversations per mailbox 2021-05-18 00:58:19 -07:00
FreeScout
f132f88059 Improve conversations pagination 2021-05-18 00:54:16 -07:00
FreeScout
38ff9e748a Allow to pass params to conversations table template 2021-05-17 23:05:50 -07:00
FreeScout
c299e0c3e2 mailbox.sidebar_folder_url hook 2021-05-17 23:05:26 -07:00
FreeScout
d4127889c3 Filter to disable mailbox sidebar buttons 2021-05-17 06:01:43 -07:00
FreeScout
994ead0e3e Hook after mailbox sidebar - closes #1209 2021-05-17 05:54:15 -07:00
FreeScout
3e5900b1e0 Merge branch 'master' of github.com:freescout-helpdesk/freescout into dist 2021-05-14 11:20:54 -07:00
FreeScout
f579c43b29 v1.7.6 2021-05-14 11:19:56 -07:00
FreeScout
f2fee6779d thread.attachments_list_append hook 2021-05-14 10:42:54 -07:00
FreeScout
4abb7ecc46 Improved createZipArchive() function 2021-05-14 10:37:16 -07:00
FreeScout
7e8fa56bf5 Add link to remind license keys 2021-05-11 07:13:25 -07:00
FreeScout
ce02ba86db Merge branch 'master' of github.com:freescout-helpdesk/freescout into dist 2021-05-11 02:46:23 -07:00
FreeScout
7fcb585268 v1.7.5 2021-05-11 02:45:24 -07:00
FreeScout
e143280c6c getFileContents() function for Attachment 2021-05-11 02:42:52 -07:00
FreeScout
f82d36afb0 Improve no_activations_left message 2021-05-09 10:33:37 -07:00
FreeScout
e14d899ac4 Fix createExtended Thread method 2021-04-30 10:30:03 -07:00
FreeScout
6a16cbabd2 Fix search in PostgreSQL - closes #1174 2021-04-29 01:39:31 -07:00
FreeScout
e52711d592 Process incoming email even if imap_mime_header_decode fails - closes #351 2021-04-29 00:38:21 -07:00
FreeScout
abc01538f9 Merge branch 'master' of github.com:freescout-helpdesk/freescout into dist 2021-04-23 00:13:23 -07:00
FreeScout
6eaf4359b5 v1.7.4 2021-04-23 00:13:14 -07:00
FreeScout
728959332b Merge branch 'master' of github.com:freescout-helpdesk/freescout into dist 2021-04-23 00:11:58 -07:00
FreeScout
d58a0981c4 Merge branch 'master' of github.com:freescout-helpdesk/freescout into dist 2021-04-22 22:47:21 -07:00
FreeScout
23cdcffb12 v1.7.3 2021-04-22 22:46:42 -07:00
FreeScout
944363765a Update readme 2021-04-22 00:09:13 -07:00
FreeScout
ace3bdbb8f Add State filter to search to filter Deleted conversations - closes #912 2021-04-21 06:16:23 -07:00
FreeScout
7926b9fd0f Compare exact conversation number and id when searching - closes #1174 2021-04-21 05:11:28 -07:00
FreeScout
4617b34478 Fix showing floating alert after sending a reply - closes #1119 2021-04-21 04:56:53 -07:00
FreeScout
7fcda1f0e7 Update readme 2021-04-21 02:08:36 -07:00
FreeScout
a72842cafe Update hit counter code in readme 2021-04-21 01:57:51 -07:00
FreeScout
8ffbfd5653 Update German translation 2021-04-21 01:47:01 -07:00
FreeScout
955681886f Merge branch 'master' of github.com:freescout-helpdesk/freescout into dist 2021-04-15 05:40:55 -07:00
FreeScout
066656adf8 Update readme 2021-04-15 05:38:47 -07:00
FreeScout
a5db2a49a8 Merge branch 'master' of github.com:freescout-helpdesk/freescout into dist 2021-04-15 00:59:45 -07:00
FreeScout
4a5dd111d7 v1.7.2 2021-04-15 00:57:40 -07:00
FreeScout
73d260c2db Add meta to Customer 2021-04-15 00:57:02 -07:00
FreeScout
c86e895ea9 thread.body_output hook 2021-04-14 23:49:22 -07:00
FreeScout
208bdb28fe Merge branch 'master' of github.com:freescout-helpdesk/freescout into dist 2021-04-14 00:10:38 -07:00
FreeScout
70b3b2f75b v1.7.1 2021-04-14 00:09:38 -07:00
FreeScout
8f35603493 Rename extra hooks in conversations table 2021-04-14 00:05:22 -07:00
FreeScout
1c592e6713 Merge pull request #1149 from droogadulce/master
Add hooks to conversations table
2021-04-14 10:02:02 +03:00
FreeScout
b0d22fc035 Merge branch 'master' of github.com:freescout-helpdesk/freescout 2021-04-14 00:00:08 -07:00
FreeScout
7f5c9dd4ef Allow to override system email footer 2021-04-13 05:41:34 -07:00
FreeScout
76e2a3ef46 Do not try to send auto reply by email when Chat/Messenger message received - closes #1151 2021-04-13 05:11:29 -07:00
FreeScout
9c48b0054f Update PL translaiton 2021-04-13 01:32:50 -07:00
droogadulce
72db97df79 Hook to show followers in the mailbox dashboard 2021-04-09 20:52:32 -05:00
FreeScout
a8b8b49dce Merge pull request #1131 from fulldecent/dist
Occurend -> occured, fixes #1130
2021-04-09 09:22:50 +03:00
William Entriken
26f9939bff Fix typo: occurend -> occurred 2021-04-04 20:10:51 -04:00
FreeScout
37ec94c157 Merge pull request #1136 from droogadulce/translations
Update Spanish translations
2021-04-03 07:51:30 +03:00
droogadulce
b336b2e54e Update Spanish translations 2021-04-02 19:35:17 -06:00
FreeScout
91a0cecffa Add vendor files to dist 2021-03-31 00:51:49 -07:00
FreeScout
a59204cd99 Merge branch 'master' of github.com:freescout-helpdesk/freescout into dist 2021-03-31 00:37:55 -07:00
FreeScout
cd61c3fd8d v1.7.0 2021-03-31 00:36:53 -07:00
FreeScout
34082cb122 PHP 8 support - closes #1002 2021-03-31 00:35:40 -07:00
FreeScout
70d92cef40 Fix readme hits counter 2021-03-25 00:00:55 -07:00
FreeScout
b3c1a97f3d Update Japanese translation 2021-03-24 23:22:56 -07:00
FreeScout
f3aa63aa13 Merge branch 'master' of github.com:freescout-helpdesk/freescout into dist 2021-03-17 01:33:23 -07:00
FreeScout
27c8753b3a v1.6.20 2021-03-17 01:32:22 -07:00
FreeScout
d352007cd2 Merge pull request #1101 from tillmon/master
Fix prefill_to
2021-03-17 11:27:08 +03:00
FreeScout
3fe95f4362 Allow customer options in fsAjax function 2021-03-16 10:24:37 -07:00
FreeScout
f13a201c56 Allow to pass UploadedFile as attachment when creating a Thread 2021-03-16 10:24:17 -07:00
tillmon
d4ca8c77b5 Fix prefill_to 2021-03-16 08:16:38 +01:00
FreeScout
920690e504 Merge branch 'master' of github.com:freescout-helpdesk/freescout into dist 2021-03-13 22:21:03 -08:00
FreeScout
282eebce76 v1.6.19 2021-03-13 22:19:45 -08:00
FreeScout
abeddf8c65 binaryDataMimeType() helper function 2021-03-13 22:18:47 -08:00
FreeScout
826cafc3a9 Return data in create() functions 2021-03-13 02:18:38 -08:00
FreeScout
04422376f2 Send full email history when forwardning global settings is non - closes #1087 2021-03-10 22:40:05 -08:00
FreeScout
f88f805f28 Merge branch 'master' of github.com:freescout-helpdesk/freescout into dist 2021-03-07 09:07:55 -08:00
FreeScout
bfe4ec2818 Merge branch 'master' of github.com:freescout-helpdesk/freescout into dist 2021-03-07 09:01:40 -08:00
FreeScout
9e07d636a8 v1.6.18 2021-03-07 09:00:59 -08:00
FreeScout
b10211dcf9 Update Polish translation 2021-03-07 08:59:24 -08:00
FreeScout
9a7c88efbf mail.process_swift_message header 2021-03-07 08:48:11 -08:00
FreeScout
a0750dddfc Outgoing emails type header 2021-03-07 08:47:47 -08:00
FreeScout
90b0100048 Show more detailed error when module manifest file can not be cached 2021-03-05 00:40:03 -08:00
FreeScout
bbb5763b8c Play audio attachments in browser 2021-03-03 23:40:54 -08:00
FreeScout
b029070d94 Merge branch 'master' of github.com:freescout-helpdesk/freescout into dist 2021-03-03 03:41:42 -08:00
FreeScout
499b2dc748 v1.6.17 2021-03-03 03:40:27 -08:00
FreeScout
153f1cbd31 Update German translation 2021-03-03 03:23:53 -08:00
FreeScout
9247f96679 Helper remoteFileName() function 2021-03-03 03:23:23 -08:00
FreeScout
d18d138f73 Include images links into plain text emails 2021-03-03 01:58:41 -08:00
FreeScout
36f0686cf4 Improve video attachment type detection 2021-03-03 00:08:10 -08:00
FreeScout
963e637931 Conversation subjectFromText() function 2021-03-02 23:45:06 -08:00
FreeScout
570d5bc60b Disable merging and fowarding for chat conversations 2021-03-02 04:50:18 -08:00
FreeScout
4c37af4976 Allow only plain text in chat conversations 2021-03-02 04:25:31 -08:00
FreeScout
f09fbdba72 Send chat conversation reply 2021-03-02 04:10:13 -08:00
FreeScout
17cd4b0460 Clean up chat conversation reply area 2021-03-02 02:17:03 -08:00
FreeScout
02e234a627 Show new message alert in the title when new message arrives 2021-03-02 01:13:53 -08:00
FreeScout
79c13c7f31 Show immediately new chat messages 2021-03-01 23:57:07 -08:00
FreeScout
c86ae98d04 Do not allow to change chat conversation customer 2021-03-01 23:03:18 -08:00
FreeScout
aec129f6bb Show customer channel as tag 2021-03-01 23:00:31 -08:00
FreeScout
b7d6e06530 Show conversation channel tags 2021-03-01 22:50:19 -08:00
FreeScout
d1fc654e36 Functions to create Conversation and Thread 2021-03-01 22:07:19 -08:00
FreeScout
1e99dbe589 Customer setPhotoFromRemoteFile() function 2021-03-01 06:20:00 -08:00
FreeScout
80a5f6188b Add channel columns to Customer and Conversation 2021-03-01 06:19:19 -08:00
FreeScout
265728dc38 Add gmail_quote to the outgoing emails to customers to let other systems better separate replies 2021-02-26 02:03:20 -08:00
FreeScout
863a29dbe6 Fix an issue with sending multiple duplicate emails #870, #1041 2021-02-26 00:39:47 -08:00
FreeScout
b28330ed56 Merge branch 'master' of github.com:freescout-helpdesk/freescout into dist 2021-02-25 07:05:44 -08:00
FreeScout
4ec7666985 1.6.16 2021-02-25 07:04:26 -08:00
FreeScout
63cf643300 Deactivate a module when its folder renamed 2021-02-25 06:44:43 -08:00
FreeScout
85c167a5f4 Update JA translation 2021-02-24 23:40:44 -08:00
FreeScout
1f4fbbd5f8 Update RU translation 2021-02-23 23:12:56 -08:00
FreeScout
d9405428d6 Fix invitation email text - closes #1066 2021-02-23 23:12:33 -08:00
FreeScout
91280c2177 Fix Row size too large error on adding meta column to mailboxes - closes #1058 2021-02-17 09:28:19 -08:00
FreeScout
9abba00fe1 Readme update 2021-02-12 21:24:02 -08:00
FreeScout
cd2b36e5c7 Merge branch 'master' of github.com:freescout-helpdesk/freescout into dist 2021-02-12 21:18:56 -08:00
FreeScout
8552d7e825 v1.6.15 2021-02-12 21:18:08 -08:00
FreeScout
5e1e9399cc Japanese language added 2021-02-12 21:13:45 -08:00
FreeScout
6a5e4af0f3 Update readme 2021-02-12 06:18:06 -08:00
FreeScout
38b31fce3c Allow to attach files in the mailbox signature 2021-02-12 04:24:56 -08:00
FreeScout
c5fa140d07 Clarification on Translate page 2021-02-12 01:32:00 -08:00
FreeScout
e13f1cf73a Update readme 2021-02-11 22:41:10 -08:00
FreeScout
03ff3f7257 Merge branch 'master' of github.com:freescout-helpdesk/freescout into dist 2021-02-10 04:02:01 -08:00
FreeScout
4c990f43a7 v1.6.14 2021-02-10 04:01:07 -08:00
FreeScout
75497aa031 downloadRemoteFileAsTmpFile() function 2021-02-10 04:00:15 -08:00
FreeScout
a8c69d1cec Adjust navbar brand text 2021-02-09 22:44:42 -08:00
FreeScout
dc4c1b9b2f Determine number of changed translations when publishing and sending 2021-02-09 05:02:57 -08:00
FreeScout
1ef654578e Optimize Translations page 2021-02-09 04:51:17 -08:00
FreeScout
a610fe2fd2 fr and pt-PT translations 2021-02-09 00:55:15 -08:00
FreeScout
97cbb8a03f Update polish translations 2021-02-08 23:41:36 -08:00
FreeScout
0e28127851 .accordion-disabled style 2021-02-08 21:49:07 -08:00
FreeScout
c7c41805d8 Fix highlighting selected top menu item 2021-02-05 23:54:01 -08:00
FreeScout
6cef45d3bd Mailbox setMetaParam method 2021-02-05 23:01:01 -08:00
FreeScout
ded05a5408 Add meta column to mailboxes table 2021-02-05 21:37:50 -08:00
FreeScout
361a4cc242 getGlobalEntity() helper method 2021-02-05 04:59:30 -08:00
FreeScout
6cfed6c229 Update readme 2021-02-03 06:01:20 -08:00
FreeScout
e8d62ab190 Update readme 2021-02-03 05:59:06 -08:00
FreeScout
7a027c4149 Tools to readme 2021-02-03 05:56:34 -08:00
FreeScout
425de91c57 Show email header in plain text emails 2021-01-29 22:50:51 -08:00
FreeScout
d50aef3832 Merge pull request #1023 from fvdm/fix-730
Fixed custom reply separator - closes #730
2021-01-30 09:11:20 +03:00
Franklin
afe2b1b8ce Fixed syntax typo 2021-01-29 01:56:21 +01:00
Franklin
566fff6c0c Fallback to default reply separator if not set 2021-01-29 01:40:09 +01:00
Franklin
88b9c926c4 Fixed custom reply separator 2021-01-28 20:19:02 +01:00
FreeScout
2db13a7ec1 Fix customer setData issue on importing - closes #1013 2021-01-24 08:48:15 -08:00
FreeScout
4d6b740f30 Merge branch 'master' of github.com:freescout-helpdesk/freescout into dist 2021-01-16 04:50:17 -08:00
FreeScout
9a8025777b v1.6.13 2021-01-16 04:49:40 -08:00
FreeScout
715bc2ecbd Use divs in emails to customers instead of tables - closes #923 2021-01-16 04:48:39 -08:00
FreeScout
e05c456f99 Update User savePhoto() function 2021-01-16 00:21:08 -08:00
FreeScout
3c4459bbac downloadRemoteFileAsTmp() helper function 2021-01-16 00:20:46 -08:00
FreeScout
cd128c5683 Merge pull request #1001 from TimoStramann/patch-1
Fix German translation
2021-01-15 12:34:15 +03:00
Timo Stramann
b4cfec133d Fix German translation
Correct wrongly translated strings
2021-01-15 09:51:29 +01:00
FreeScout
408c5351bf Do not send multiple emails to customers when saving outgoing reply to IMAP folder fails - closes #984 2021-01-14 23:58:14 -08:00
FreeScout
6fd295211b Update pt-PT translation 2021-01-14 23:29:49 -08:00
FreeScout
6e9db6d7c9 Update German translation 2021-01-14 23:28:40 -08:00
FreeScout
cd4964401f Make conversations table in customer profile wider 2021-01-07 02:31:52 -08:00
FreeScout
7572febd8d Improve .navbar-brand-with-text vertical alignment 2021-01-06 00:14:26 -08:00
FreeScout
90180b890d Merge branch 'master' of github.com:freescout-helpdesk/freescout into dist 2020-12-31 00:32:56 -08:00
FreeScout
1e6b0ac6a9 1.6.12 2020-12-31 00:32:02 -08:00
FreeScout
6ab9b5fba7 Do not show empty To field in thread 2020-12-30 05:11:07 -08:00
FreeScout
b9cbf749be Do not send notifications on imported conversations 2020-12-30 03:18:11 -08:00
FreeScout
ea7de1c085 Do not hightlight dashboard folders on hover 2020-12-29 22:12:09 -08:00
FreeScout
eaa681dfc3 Show customer data on a new line 2020-12-29 01:47:04 -08:00
FreeScout
2d79c3df9f Update Polish translations 2020-12-24 23:25:56 -08:00
FreeScout
649134bd22 Increase a bit logo size 2020-12-24 22:48:59 -08:00
FreeScout
abf3192476 Settings stored in .env file no being updated after clicking Save button 2020-12-24 02:22:22 -08:00
FreeScout
b7a2312994 Merge branch 'master' of github.com:freescout-helpdesk/freescout into dist 2020-12-23 23:42:30 -08:00
FreeScout
4d6d16a58b v1.6.11 2020-12-23 23:41:47 -08:00
FreeScout
4d389dcfa3 Highlight headers in the dashboard 2020-12-23 23:37:42 -08:00
FreeScout
01fa48df18 menu_right.user.after_profile hook 2020-12-23 21:54:36 -08:00
FreeScout
3fedf57b72 Improve fetch_emails.unseen hook 2020-12-23 21:52:12 -08:00
FreeScout
3140c2e90c Merge pull request #959 from tillmon/unseen
Fetch emails hook unseen
2020-12-24 08:45:27 +03:00
FreeScout
5fbab18684 Permission to allow users manage users 2020-12-22 23:48:15 -08:00
Tillmann Baumgart
1fc7c4d53d fetch emails hook unseen 2020-12-23 08:16:57 +01:00
FreeScout
2f14216e49 User Permissions per User - closes #741 2020-12-22 10:07:42 -08:00
FreeScout
ae602a2f6f Hide Delete Conversation button if user does not have permissions 2020-12-22 02:26:20 -08:00
FreeScout
08c701a3eb Store user permissions in .env instead of Options 2020-12-22 02:22:35 -08:00
FreeScout
40cebf61c2 Delete send logs older 6 months 2020-12-21 07:04:11 -08:00
FreeScout
c6fa18fe8d Support RTL languages with HTML dir attribute - closes #924 2020-12-21 04:09:54 -08:00
FreeScout
3598d5efdf Merge branch 'master' of github.com:freescout-helpdesk/freescout into dist 2020-12-16 23:40:59 -08:00
FreeScout
0b305ec22f v1.6.10 2020-12-16 23:40:20 -08:00
FreeScout
fe694de119 Improve set closed_at if conversation is closed after reply 2020-12-16 23:37:16 -08:00
FreeScout
74bb03f92e Merge pull request #941 from tillmon/dev2
Set closed_at if conversation is closed after reply
2020-12-17 10:18:58 +03:00
FreeScout
3446abd7d8 Improve prefilling To address in new conversation 2020-12-16 23:14:38 -08:00
FreeScout
ed0cc6c9be Merge branch 'master' of github.com:freescout-helpdesk/freescout 2020-12-16 23:10:35 -08:00
FreeScout
ef8d6ddf07 customer.profile_preview_prepend hook 2020-12-16 23:10:30 -08:00
FreeScout
3a3dd05393 Adjust transparent button color 2020-12-16 23:10:18 -08:00
FreeScout
f6417a3bd5 Merge pull request #940 from tillmon/dev
Set "to" in new conversation with url parameter
2020-12-17 10:08:35 +03:00
Tillmann Baumgart
49df4425ea set closed_at if conversation is closed after reply 2020-12-16 22:39:07 +01:00
Tillmann Baumgart
758129d035 set "to" in new conversation with url parameter 2020-12-16 22:38:06 +01:00
FreeScout
608e6e7a1d Hightlight new Unassigned and Mine conversations in the dashboard 2020-12-16 01:20:45 -08:00
FreeScout
6cffdba578 Adjust transparent button color 2020-12-16 00:52:43 -08:00
FreeScout
9b64cc270a Condense dashboard content 2020-12-16 00:45:30 -08:00
FreeScout
cc5526f7f3 Adjust logo brightness on hover 2020-12-16 00:39:35 -08:00
FreeScout
77ed94a2e8 Fix deactivating licenses 2020-12-05 10:19:38 -08:00
FreeScout
54657e5dc7 Fix deactivating licenses 2020-12-05 09:59:45 -08:00
FreeScout
62bc3dd614 Merge branch 'master' of github.com:freescout-helpdesk/freescout into dist 2020-12-03 03:18:52 -08:00
FreeScout
ec7f10d119 v1.6.9 2020-12-03 03:17:54 -08:00
FreeScout
50f22ccf25 Allow encoded settings using env_encode parameter 2020-12-03 02:24:43 -08:00
FreeScout
9ae4a5053a Properly separate replies from FreeScout to FreeScout - closes #765 2020-12-02 22:32:32 -08:00
FreeScout
807bddeace Show conversation status icon in the list 2020-12-02 06:11:25 -08:00
FreeScout
74ce6ca353 Show user name when deleting a user 2020-12-02 05:49:24 -08:00
FreeScout
cb10380498 Make customer messages editable - closes #896 2020-12-02 05:39:56 -08:00
FreeScout
490f850834 Merge branch 'master' of github.com:freescout-helpdesk/freescout into dist 2020-11-26 01:47:12 -08:00
FreeScout
9bd75acdba v1.6.8 2020-11-26 01:46:19 -08:00
FreeScout
e8e8bd3262 Fix displaying fields in customer profile 2020-11-26 01:08:21 -08:00
FreeScout
55411f7979 Customer hooks 2020-11-25 06:11:45 -08:00
FreeScout
40e8d39f75 Properly process arrays in getQueryParam() 2020-11-25 06:11:02 -08:00
FreeScout
bd81680cdb Fix notifications dropdown in German language - closes #874 2020-11-24 05:15:02 -08:00
FreeScout
fa557969df Do not fill automatically CC or BCC when forwarding - closes #877 2020-11-24 04:40:05 -08:00
FreeScout
2a5f92eaf2 Custom 403 page 2020-11-24 04:29:34 -08:00
FreeScout
7cd5dd9929 Allow only admin to manage mailbox connection settings - closes #881 2020-11-24 04:22:49 -08:00
FreeScout
a6f18efbc7 Update German translations 2020-11-24 04:13:07 -08:00
FreeScout
fedaa33741 conversation.view.focus event 2020-11-21 22:15:57 -08:00
FreeScout
1eadd06f9d customer.edit.after_fields hook 2020-11-20 22:47:15 -08:00
FreeScout
4f1c2731bf Trigger conversation.view.start when focus returns to conversation 2020-11-20 22:41:51 -08:00
FreeScout
00b52794aa Remove conversation viewer when conversation window is not in focus 2020-11-20 21:27:39 -08:00
FreeScout
f9c2799526 Remove conversation viewer when conversation window is not in focus 2020-11-20 21:15:21 -08:00
FreeScout
bd1278aab4 Show customer social profiles 2020-11-19 03:13:17 -08:00
FreeScout
4f8063214f Rename customer background into notes, delete age, gender fields 2020-11-19 01:15:00 -08:00
FreeScout
fcdf2fba0e Allow to add customer photo 2020-11-18 23:23:55 -08:00
FreeScout
a8479fb315 Show customer social profiles 2020-11-18 23:09:18 -08:00
FreeScout
9fc473efb1 Remove nginx client_max_body_size from system status as it can not be retrieved 2020-11-18 20:45:02 -08:00
FreeScout
712785dc44 New fields added to customer profiles 2020-11-18 06:11:01 -08:00
FreeScout
f904057944 Pagination in customers search 2020-11-18 02:05:43 -08:00
FreeScout
4cc750ec0f Improve conversations navigation 2020-11-18 01:31:21 -08:00
FreeScout
f97f43f49b Misc updates in customers 2020-11-18 00:42:05 -08:00
FreeScout
826e42085c Update search 2020-11-17 21:59:24 -08:00
FreeScout
4e555f3198 Allow embed mode using x_embed parameter 2020-11-17 21:57:55 -08:00
FreeScout
df5d23abbc Pass x_ parameters globally, xs_ parameters only on the same page 2020-11-17 21:56:55 -08:00
FreeScout
8041f6b268 Do not redirect user to the anaccessible mailbox after moving conversations 2020-11-16 06:32:48 -08:00
FreeScout
f22e2d6d93 Update German translation 2020-11-16 05:46:37 -08:00
FreeScout
d770b218f2 Improve attachment download link 2020-11-16 05:07:14 -08:00
FreeScout
93d640206f Merge pull request #871 from Filoz/patch-1
Add download button to attachment
2020-11-16 16:04:42 +03:00
Filippo Lazzarini
19d66a3cb2 Update thread_attachments.blade.php 2020-11-16 10:22:22 +01:00
Filippo Lazzarini
9819668246 Add download button to attachment 2020-11-16 10:18:51 +01:00
FreeScout
944a29814b Show PHP upload_max_filesize / post_max_size 2020-11-15 07:12:13 -08:00
FreeScout
b09ef174ab Do not show deleted users when creating a new mailbox - closes #866 2020-11-15 06:56:28 -08:00
FreeScout
aebf33c2f0 Merge branch 'master' of github.com:freescout-helpdesk/freescout into dist 2020-11-07 04:09:16 -08:00
FreeScout
5e59b7b561 v1.6.7 2020-11-07 04:08:26 -08:00
FreeScout
f47efb8f5f Customer parseName() function 2020-11-07 00:36:56 -08:00
FreeScout
c562b9525a Customer parseName() function 2020-11-06 05:47:38 -08:00
FreeScout
06593afb95 .navbar-brand-with-text style 2020-11-06 05:47:23 -08:00
FreeScout
9d09869f80 localStorageGetObject() and localStorageSetObject() JS functions 2020-11-06 05:47:05 -08:00
FreeScout
32ecbfc718 Make foreign keys fields unsigned - closes #853 2020-11-04 22:41:11 -08:00
FreeScout
ae6fdeef29 Fix starring conversations - closes #662 2020-11-04 05:47:04 -08:00
FreeScout
bbd0cdee78 Check non-writable cache files in System Status 2020-10-31 04:37:41 -07:00
FreeScout
76ab984e0b Merge branch 'master' of github.com:freescout-helpdesk/freescout into dist 2020-10-31 00:07:11 -07:00
FreeScout
c61c9c86c8 v1.6.6 2020-10-31 00:06:33 -07:00
FreeScout
90e29f8b43 Check non-writable cache files in System Status 2020-10-31 00:04:57 -07:00
FreeScout
e7ab1e4296 .input-group-addon-grey style 2020-10-30 01:09:41 -07:00
FreeScout
e5017a2031 Fix showing Settings updated alert 2020-10-29 22:59:11 -07:00
FreeScout
02ff35a306 Show number of users in Users 2020-10-29 02:38:14 -07:00
FreeScout
c3b90d7952 Fix recipient name on forwarding - closes #786 2020-10-28 23:49:54 -07:00
FreeScout
f9ba58c6f1 Change Remove Formatting button icon 2020-10-28 23:13:43 -07:00
FreeScout
69da2dbd18 Allow headers when viewing threads 2020-10-28 08:02:55 -07:00
FreeScout
308b4a9ecd Allow pre tags when viewing threads 2020-10-28 07:57:09 -07:00
FreeScout
1256f02c13 Change Remove Formatting button icon 2020-10-28 04:50:32 -07:00
FreeScout
b3ee050eb3 Merge branch 'master' of github.com:freescout-helpdesk/freescout into dist 2020-10-27 23:49:58 -07:00
FreeScout
ead26a92c4 v1.6.5 2020-10-27 23:49:24 -07:00
FreeScout
2e4dca4d89 In user notification use the username part of the email address if customer has no name - closes #749 2020-10-27 23:14:23 -07:00
FreeScout
b4d1e3eaff Add quotes when settings .env vars 2020-10-27 22:40:41 -07:00
FreeScout
8a5fa4f158 Merge branch 'master' of github.com:freescout-helpdesk/freescout into dist 2020-10-27 02:39:06 -07:00
FreeScout
fcacca3495 v1.6.4 2020-10-27 02:38:16 -07:00
FreeScout
6e71478598 Fix Unknown system variable sql_require_primary_key - closes #834 2020-10-27 02:37:38 -07:00
FreeScout
e982a8a799 Merge branch 'master' of github.com:freescout-helpdesk/freescout into dist 2020-10-26 02:18:10 -07:00
FreeScout
b591947fac v1.6.3 2020-10-26 02:16:53 -07:00
FreeScout
6ed171fc8f Footer hook 2020-10-26 01:39:48 -07:00
FreeScout
48f68f82dd Escape settings containing quotes 2020-10-26 01:39:34 -07:00
FreeScout
70fbc0c24a Fix insertVar option in summernoteInit() 2020-10-26 01:39:15 -07:00
FreeScout
27049809ef Forwarding to multiple recipients - closes #825 2020-10-25 23:48:14 -07:00
FreeScout
5b4ff8b5c2 include_attachments parameter for Conversation forward() function 2020-10-25 00:04:19 -07:00
FreeScout
0f581ad9cb Check connection only for SMTP send method - closes #828 2020-10-24 07:39:40 -07:00
FreeScout
edf9163ca1 Show full date when printing a conversation - closes #783 2020-10-24 02:37:32 -07:00
FreeScout
83b6e82c1d Update pt-PT translation 2020-10-24 02:29:44 -07:00
FreeScout
c0e54d44c4 Fix File name too long - closes #806 2020-10-24 02:25:46 -07:00
FreeScout
03f20e7ec7 Fix double image on print screen - closes #694 2020-10-24 01:04:58 -07:00
FreeScout
c1e9d01099 Fix sql_require_primary_key issue - closes #818 2020-10-24 00:04:02 -07:00
FreeScout
0f4f2674f7 Fix sql_require_primary_key issue - closes #818 2020-10-23 11:39:42 -07:00
FreeScout
6e752bba1c Merge branch 'master' of github.com:freescout-helpdesk/freescout 2020-10-23 06:12:59 -07:00
FreeScout
077d6ba8a4 Merge pull request #792 from Servery/patch-3
Update de.json (2nd try)
2020-10-23 16:12:28 +03:00
FreeScout
0e3b9d9c1d Update readme 2020-10-07 10:23:10 -07:00
Tim Schulenburg
21edb60c16 Update de.json (2nd try)
Line 201: Missing ":" to display german text with a href correct.
Line 358: Old translation does not sound good in german.
Line 727 - 747: Added some translations
2020-10-07 17:21:46 +02:00
FreeScout
b38cd59b42 Update readme 2020-10-06 02:28:13 -07:00
FreeScout
fbf88be324 Merge branch 'master' of github.com:freescout-helpdesk/freescout into dist 2020-10-06 01:46:01 -07:00
FreeScout
cfa228083d v1.6.2 2020-10-06 01:45:22 -07:00
FreeScout
b9b36e31d2 Merge pull request #788 from injektion/permissions-scroll
make permissions manager scrollable on mobile screens
2020-10-06 11:41:37 +03:00
FreeScout
f25259e78b iOS app link to the Notifications settings 2020-10-06 01:10:25 -07:00
FreeScout
7e24125fe3 iOS to readme 2020-10-06 01:07:34 -07:00
FreeScout
e237f76b0f Remove api routes 2020-10-06 00:27:32 -07:00
FreeScout
a5c9a8cea6 Improve customer creation function 2020-10-06 00:26:50 -07:00
M@
7dca17f2aa make permissions manager scrollable on mobile screens 2020-10-05 13:43:37 -07:00
FreeScout
2befc5c172 Helper::isDev() function 2020-10-04 10:33:08 -07:00
FreeScout
8a667cb8a2 Run second migration after the module has been activated - closes #773 2020-10-02 04:53:12 -07:00
FreeScout
fde1e96104 Do not cut out regular Gmail quotes - closes #778 2020-10-02 01:18:13 -07:00
FreeScout
13ad09022b Fix in_array() expects parameter 2 to be array in BroadcastNotification - closes #761 2020-10-02 01:00:47 -07:00
FreeScout
7c248803dd Do no show Disable User checkbox to non-admins 2020-10-02 00:24:31 -07:00
FreeScout
b4b440f871 Hide New Mailbox button from non-admins 2020-10-02 00:21:42 -07:00
FreeScout
86c29a89c2 Added proc_open to the list of required functions in System Status 2020-10-02 00:19:15 -07:00
FreeScout
ac3255efb5 Merge branch 'master' of github.com:freescout-helpdesk/freescout into dist 2020-10-02 00:08:30 -07:00
FreeScout
24acd8e2fe v1.6.1 2020-10-02 00:07:43 -07:00
FreeScout
a243d7a0ff Printing conversations, messages and notes - closes #507 2020-09-28 00:58:34 -07:00
FreeScout
530715af17 Merging conversations to readme 2020-09-27 23:02:15 -07:00
FreeScout
10e2c0c20f Add outlook reply separator - closes #461 2020-09-27 07:38:27 -07:00
FreeScout
17b1de0825 Hide prev next arrows on small screen 2020-09-27 05:56:37 -07:00
FreeScout
882478edb1 Import email into multiple mailboxes if needed - closes #480 2020-09-27 05:07:32 -07:00
FreeScout
a5e3343f06 Improve Mailbox managers implementation - closes #490 2020-09-25 03:00:54 -07:00
FreeScout
168e4427dc Merge pull request #756 from injektion/mailbox-managers
Issue 490: Mailbox Managers and per user management permissions
2020-09-25 13:00:30 +03:00
FreeScout
069a44774e Merge pull request #760 from cloudron-io/disable-updates
WIP: Add config variable to disable update checks
2020-09-24 13:55:48 +03:00
Johannes Zellner
e67d60d088 WIP: Add config variable to disable update checks 2020-09-24 12:28:27 +02:00
M@
d1239e2e22 issue 490 - Mailbox managers with per user settings 2020-09-22 16:51:25 -07:00
FreeScout
3e1ee77c14 Merge pull request #755 from fvdm/patch-3
Added Search filters to NL translation
2020-09-22 17:40:26 +03:00
FreeScout
973f1386d0 Merge pull request #754 from fvdm/patch-2
Allow translation of search filters
2020-09-22 17:39:11 +03:00
FreeScout
077ed36a4a Merge pull request #751 from fvdm/patch-1
Added Merge strings to NL translation
2020-09-22 17:38:35 +03:00
Franklin
1841ee32f6 Added Search filters to NL translation 2020-09-22 15:50:58 +02:00
Franklin
d16a1938c2 Allow translation of search filters 2020-09-22 15:32:32 +02:00
Franklin
28f3c3be62 Added Merge strings to NL translation 2020-09-22 15:14:00 +02:00
FreeScout
1d2e0fed0e Merge branch 'master' of github.com:freescout-helpdesk/freescout into dist 2020-09-22 02:01:52 -07:00
FreeScout
065048ee46 v1.6.0 2020-09-22 02:00:55 -07:00
FreeScout
465a982080 Merge conversations - closes #226 2020-09-22 00:59:23 -07:00
FreeScout
8827fae5f3 Edit conversation subject - closes #43 2020-09-21 02:29:12 -07:00
FreeScout
3461a2d36c Added search shortcut: All from current mailbox - closes #591 2020-09-21 01:47:05 -07:00
FreeScout
19891a39e4 Add Conversation History to Send button dropdown - closes #744 2020-09-21 01:17:37 -07:00
FreeScout
b751959f42 Send full conversation history when forwarding conversation via Workflow - closes #743 2020-09-20 07:07:01 -07:00
FreeScout
721a599ed3 Merge branch 'master' of github.com:freescout-helpdesk/freescout 2020-09-17 05:09:52 -07:00
FreeScout
9caf10774b Merge pull request #737 from fvdm/issue-735
Convert subject to UTF-8 encoding
2020-09-17 15:09:34 +03:00
FreeScout
b1dd37025f Require curl extension 2020-09-17 05:06:09 -07:00
FreeScout
9b49a321bb Add shell_exec and ps to System Status page 2020-09-17 05:02:55 -07:00
Franklin
f8b0214519 Convert all subject encodings
and continue parsing on grammar error
2020-09-17 13:26:02 +02:00
Franklin
4bcc9dbc3a Optimized subject encoding conversion 2020-09-17 12:52:57 +02:00
FreeScout
4b44f3c718 Merge branch 'master' of github.com:freescout-helpdesk/freescout into dist 2020-09-16 10:32:29 -07:00
FreeScout
230ce5e405 v1.5.15 2020-09-16 10:31:37 -07:00
FreeScout
ca2bc58881 getActionTypeName() function for thread 2020-09-16 10:27:48 -07:00
FreeScout
8271ccb005 Allow empty folder parameter in getWaitingSince() 2020-09-16 02:36:23 -07:00
FreeScout
e766a9a581 customer.updated hook 2020-09-15 08:10:08 -07:00
FreeScout
b66a0a9b12 customer.created hook 2020-09-15 08:04:04 -07:00
FreeScout
fb7733f2e1 customer.created hook 2020-09-15 08:01:30 -07:00
FreeScout
d4fe8943a4 conversation.moved event 2020-09-15 07:48:13 -07:00
FreeScout
c3d6e845d0 conversation.deleted hook 2020-09-15 05:07:35 -07:00
Franklin
ba7b0843df Convert subject to UTF-8 encoding 2020-09-14 22:38:54 +02:00
FreeScout
5bbd6d474a Added .panel-padded class 2020-09-14 05:07:26 -07:00
FreeScout
e3d1d2760a settings.after_save hook 2020-09-14 05:06:13 -07:00
FreeScout
4489e171db fs_select2_config in main.js 2020-09-14 01:49:49 -07:00
FreeScout
9c32bf2328 Fix error on PostgreSQL in RealtimeMailboxNewThread - closes #731 2020-09-12 09:31:38 -07:00
FreeScout
1c687f84b7 Merge branch 'master' of github.com:freescout-helpdesk/freescout into dist 2020-09-11 04:42:33 -07:00
FreeScout
a574687253 v1.5.14 2020-09-11 04:41:49 -07:00
FreeScout
b7464a3742 Update readme 2020-09-11 04:35:02 -07:00
FreeScout
f319d2f498 Show address and country in customer profile 2020-09-11 04:11:29 -07:00
FreeScout
61bb42ae3a When creating a phone conversations try to find customer by phone number 2020-09-11 00:54:58 -07:00
FreeScout
e5bd0dfe49 Added function to save customer photo 2020-09-10 08:06:02 -07:00
FreeScout
f30adeb613 Merge branch 'master' of github.com:freescout-helpdesk/freescout into dist 2020-09-08 23:07:34 -07:00
FreeScout
ca173694f8 v1.5.13 2020-09-08 23:06:48 -07:00
FreeScout
9b04008545 Improve repeated auto reply detection - closes #688 2020-09-07 01:47:28 -07:00
FreeScout
83ca847312 auth.password_reset_available hook 2020-09-07 01:16:28 -07:00
FreeScout
19dcb55980 Add Modules folder to permissions 2020-09-06 06:42:19 -07:00
FreeScout
f1f1e19670 Update de tanslation 2020-09-06 06:39:16 -07:00
FreeScout
1bb23e2198 Search on Users page 2020-08-25 06:34:05 -07:00
FreeScout
adfd7baa46 Show emails on Users pages 2020-08-25 06:20:20 -07:00
FreeScout
c0b33e1ea5 Fix G Suite send error: Expected response code 250 but got an empty response 2020-08-25 03:42:06 -07:00
FreeScout
066bb84e5c Show Message-ID in email logs 2020-08-25 02:09:25 -07:00
FreeScout
e230ee77fd Improve rescaling images in threads 2020-08-24 23:41:06 -07:00
FreeScout
e113373eb6 Merge pull request #712 from fvdm/patch-2
Rescale large images for readability
2020-08-25 09:37:44 +03:00
Franklin
dd602cd3b6 Rescale large images for readability 2020-08-24 20:28:09 +02:00
FreeScout
ce029693cf Add vendor files to dist 2020-08-24 02:56:40 -07:00
FreeScout
497af1fe00 Merge branch 'master' of github.com:freescout-helpdesk/freescout into dist 2020-08-24 02:54:46 -07:00
FreeScout
b5e5bc0b01 Merge branch 'master' of github.com:freescout-helpdesk/freescout 2020-08-24 02:53:56 -07:00
FreeScout
051b1875e7 v1.5.12 2020-08-24 02:53:21 -07:00
FreeScout
a673f4a7f2 Merge pull request #708 from Zen-glen/master
Customer factory now generates json for 'phones' field.
2020-08-24 12:36:12 +03:00
FreeScout
bd1804589a Custom middleware hook 2020-08-23 10:22:33 -07:00
FreeScout
26409139a0 User profile menu hook 2020-08-23 10:22:00 -07:00
Glen Clark
62e44488a9 Customer factory now generates json for 'phones' field. 2020-08-23 10:57:22 +01:00
FreeScout
5def82024d Add Validate event to SessionGuard 2020-08-22 23:07:25 -07:00
FreeScout
cdb6b6d8f8 Allow to add macroses dynamically to Eloquent Models 2020-08-22 23:07:02 -07:00
FreeScout
4705c3ec8c Fix showing additional CCs in conversations - closes #703 2020-08-22 01:14:13 -07:00
FreeScout
ded547a296 Update PL translatons 2020-08-18 02:28:28 -07:00
FreeScout
c61655bb08 Merge pull request #699 from e1mo/master
Check if ORIG_SCRIPT_NAME exists before using it
2020-08-18 11:25:37 +03:00
FreeScout
eb25eeef76 Upate pr-BR translation 2020-08-18 01:11:44 -07:00
FreeScout
1de015a3ab Restore NL translation 2020-08-17 05:13:50 -07:00
e1mo
b83dbbe5d4 Check if ORIG_SCRIPT_NAME exists before using it 2020-08-16 20:02:10 +02:00
FreeScout
ed82534030 Merge branch 'master' of github.com:freescout-helpdesk/freescout into dist 2020-07-26 04:16:38 -07:00
FreeScout
94481421ac v1.5.11 2020-07-26 04:15:25 -07:00
FreeScout
3463563e42 Fix prev and next buttons in Mine folder 2020-07-26 01:26:49 -07:00
FreeScout
b6fac871e0 Main menu hooks 2020-07-26 00:38:44 -07:00
FreeScout
6221193d8c Do not show loader when automatically updating conversations - closes #643 2020-07-24 01:26:30 -07:00
FreeScout
83f14010b1 Merge branch 'master' of github.com:freescout-helpdesk/freescout into dist 2020-07-23 00:31:01 -07:00
FreeScout
adb6f8327d v1.5.10 2020-07-23 00:29:51 -07:00
FreeScout
bb7ede7998 Update user permissions 2020-07-23 00:28:54 -07:00
FreeScout
b6103a61cd folder.count filter 2020-07-20 00:57:51 -07:00
FreeScout
8ac4b2c7dd Fix folder conversations number in title 2020-07-20 00:57:40 -07:00
FreeScout
ed15907e69 Fix fetching emails in PostgreSQL 2020-07-19 03:21:42 -07:00
FreeScout
022f358e16 Sort mailboxes by name 2020-07-19 03:20:16 -07:00
FreeScout
661ce426dd Fix installation wizard with PostgreSQL - closes #654 2020-07-19 02:27:31 -07:00
FreeScout
068b89fe72 Reduce scrollable dropdown height 2020-07-19 00:54:03 -07:00
FreeScout
0924ebe33d Add missing time zones 2020-07-18 07:27:10 -07:00
FreeScout
97b7429da5 Alphabetically Sort Mailbox List on Dashboard - closes #660 2020-07-18 07:01:42 -07:00
FreeScout
cc1c392418 Fix flatpickr pt-pt.js error 2020-07-18 06:56:43 -07:00
FreeScout
1e8ce0bebf modules.show_license hook 2020-07-18 01:19:28 -07:00
FreeScout
badcdf78c1 Merge branch 'master' of github.com:freescout-helpdesk/freescout into dist 2020-07-17 07:20:59 -07:00
FreeScout
026bf60751 v1.5.9 2020-07-17 07:19:18 -07:00
FreeScout
6aee85a591 Add Conversation History option to conversations 2020-07-15 02:09:39 -07:00
FreeScout
f8e150c65d Merge branch 'master' of github.com:freescout-helpdesk/freescout 2020-07-15 01:39:04 -07:00
FreeScout
694d0ac27c Merge pull request #672 from Dirk-Kokx/master
Add Conversation History option to conversations
2020-07-15 11:38:46 +03:00
Dirk Kokx
2ad683f7dd Conversation:
changed database type and handling of the settings
2020-07-15 09:56:55 +02:00
Dirk Kokx
da367ee93f Conversation:
moved settings button to the end of the dropdown
2020-07-15 09:56:12 +02:00
Dirk Kokx
190d2304bc ...and now has a settings button to toggle the settings modal 2020-07-15 08:10:39 +02:00
Dirk Kokx
bdc39b25b7 Added conversation settings
For now this only includes history settings (an override to the global setting per conversation)
2020-07-14 22:11:36 +02:00
FreeScout
9b17434c64 Helper functions 2020-07-03 02:26:23 -07:00
FreeScout
65426df448 Merge pull request #650 from Matslom/fix-648
Fixes 648 "Hide from Assign list" in Bulk Actions
2020-07-01 06:59:14 +05:45
Mateusz Słomiński
05977c7792 Fixes 648 "Hide from Assign list" in Bulk Actions 2020-06-30 20:53:04 +02:00
FreeScout
804e92e9b7 Merge branch 'master' of github.com:freescout-helpdesk/freescout 2020-06-17 02:34:19 -07:00
FreeScout
02420b5e94 Merge pull request #639 from cloudron-io/brand-icon
Replace brand logo with svg version to support hiDPI screens
2020-06-17 15:17:28 +05:45
Johannes Zellner
b3f7016515 Replace brand logo with svg version to support hiDPI screens 2020-06-17 10:51:27 +02:00
FreeScout
96c7166a26 Remove delay when sending notifications to users 2020-06-16 21:25:26 -07:00
FreeScout
4262a1b639 Merge branch 'master' of github.com:freescout-helpdesk/freescout into dist 2020-06-15 21:27:57 -07:00
FreeScout
ad9316377d 1.5.8 2020-06-15 21:26:52 -07:00
FreeScout
c282f9c2d4 Perform second mail send attempt after 5 min 2020-06-15 19:26:08 -07:00
FreeScout
52a8ce60d9 Vertical scroll for large assignees list - closes #620 2020-06-15 19:25:08 -07:00
FreeScout
517a87438e Update German translations 2020-06-15 18:52:49 -07:00
FreeScout
cf4d03b772 Upadte NL translations 2020-06-15 18:51:16 -07:00
FreeScout
8877be24b5 Add delay when sending notifications to users to avoid blocking by G Suite Relay 2020-06-11 19:00:21 -07:00
FreeScout
1bbe9e19de Extra class for empty partial 2020-06-03 03:22:46 -07:00
FreeScout
6728f7c796 Add .glyphicon-spin class 2020-06-01 22:31:36 -07:00
FreeScout
5488f4ba3d Add .content-full class 2020-06-01 19:16:25 -07:00
FreeScout
026b4aa7cf Dont send auto reply for spam emails - closes #628 2020-06-01 19:15:42 -07:00
FreeScout
ab21227bee Convert menu.append filter into action 2020-05-28 23:17:50 -07:00
FreeScout
de0afbabde Update readme 2020-05-28 03:38:41 -07:00
FreeScout
ef033e477c Add vendor files to dist 2020-05-28 03:35:33 -07:00
FreeScout
35b2cbc490 Merge branch 'master' of github.com:freescout-helpdesk/freescout into dist 2020-05-28 03:28:03 -07:00
FreeScout
ecc031422e v1.5.7 2020-05-28 03:27:12 -07:00
FreeScout
7451223e09 Sort threads in emails to customers by thread ID instead of created_at - closes #532 2020-05-28 02:21:14 -07:00
FreeScout
9a1ae415ce Reply from customer to deleted conversation should undelete it - closes #585 2020-05-27 22:47:26 -07:00
FreeScout
e09fe00563 Do not send autoreplies to own mailboxes 2020-05-27 22:13:17 -07:00
FreeScout
0d8ae55422 Remove slug column from mailboxes table 2020-05-27 21:19:44 -07:00
FreeScout
ee508a7927 Let getInProtocolName work when protocol not set 2020-05-27 20:57:24 -07:00
FreeScout
ec8b282767 Deactivate license from Modules page 2020-05-27 03:05:06 -07:00
FreeScout
face17249d PHP 7.4 support 2020-05-27 02:59:01 -07:00
FreeScout
ce182c9fa5 Fix Select all in next page - closes #618 2020-05-27 01:36:52 -07:00
FreeScout
b25a59e748 PHP 7.4 support - closes #432 2020-05-26 03:45:33 -07:00
FreeScout
3b0c50329a Fix error when moving conversation to the mailbox where current assignee is not present 2020-05-26 03:36:23 -07:00
FreeScout
420245e66a Merge pull request #617 from springboardVR/feature/postgres
Postgres Support
2020-05-26 14:10:51 +05:45
Matthew Hall
dd9db08431 Postgres support 2020-05-20 09:00:21 -04:00
FreeScout
f8122d5fb3 Fix viewers icons on mobile 2020-05-16 21:24:22 -07:00
FreeScout
90975c31d2 Fix sidebar buttons width 2020-05-16 21:20:07 -07:00
FreeScout
8dd630b43b Merge branch 'master' of github.com:freescout-helpdesk/freescout into dist 2020-05-16 03:45:30 -07:00
FreeScout
25a41858fd v1.5.6 2020-05-16 03:44:02 -07:00
FreeScout
d20986949b Updated translations: de, es, fr, pl 2020-05-16 03:42:17 -07:00
FreeScout
bc60281379 Allow to cancel queued job - closes #606, #611 2020-05-16 03:17:42 -07:00
FreeScout
84b3df80e2 View some attachments in browser instead of downloading - closes #609 2020-05-15 21:11:37 -07:00
FreeScout
8923315995 Show mailbox in search 2020-05-15 19:10:14 -07:00
FreeScout
528b4584ac Fix sorting in search - closes ##608 2020-05-14 04:44:27 -07:00
FreeScout
c14d2c3867 Show no subject for previous conversations without a subject 2020-05-14 01:58:00 -07:00
FreeScout
be3081de42 New reply separator 2020-05-14 01:54:24 -07:00
FreeScout
c46e0d9811 Merge branch 'master' of github.com:freescout-helpdesk/freescout into dist 2020-05-08 20:48:25 -07:00
FreeScout
f00df1c17a v1.5.5 2020-05-08 20:47:44 -07:00
FreeScout
684f8769a1 In customer profile show only conversation from mailboxes available for the user - closes #587 2020-05-08 20:46:34 -07:00
FreeScout
956888956e Preserve the thread id if any for reply copies 2020-05-08 19:27:36 -07:00
FreeScout
d8de1f86cf Merge branch 'master' of github.com:freescout-helpdesk/freescout 2020-05-08 19:17:58 -07:00
FreeScout
4be4b84622 Merge pull request #600 from cloudron-io/preserve-thread-id-for-reply-copies
Preserve the thread id if any for reply copies
2020-05-09 08:02:27 +05:45
FreeScout
ce1fbb5e05 Fix redirect to the folder after changing conversation status 2020-05-08 19:14:43 -07:00
Johannes Zellner
c29a7cd693 Preserve the thread id if any for reply copies 2020-05-02 14:05:29 +02:00
FreeScout
b69361abf2 Merge pull request #596 from fvdm/patch-1
Update NL translation
2020-05-02 17:37:29 +05:45
Franklin
e7e50bee35 Reordered keys NL translation 2020-04-30 12:08:23 +02:00
Franklin
2cef319a32 Update NL translation 2020-04-30 12:06:41 +02:00
Franklin
9df7c18181 Update NL translation 2020-04-30 11:49:21 +02:00
FreeScout
b4229070e6 Merge branch 'master' of github.com:freescout-helpdesk/freescout into dist 2020-04-26 03:11:24 -07:00
FreeScout
c11632f8ef 1.5.4 2020-04-26 03:10:30 -07:00
FreeScout
972cd5e645 Fix an array to string conversion error 2020-04-26 03:02:06 -07:00
FreeScout
87e606699d Improve saving reply emails to IMAP folder 2020-04-26 02:53:02 -07:00
FreeScout
5da4dee1cb Merge pull request #577 from cloudron-io/copy-reply-to-sent
Save reply email to mailbox
2020-04-26 15:00:42 +05:45
FreeScout
0d44809496 Merge branch 'master' of github.com:freescout-helpdesk/freescout 2020-04-25 03:54:33 -07:00
FreeScout
74e0108d76 Update readme 2020-04-25 03:54:19 -07:00
Johannes Zellner
243fe9c756 Save reply email to mailbox
If reply_folder is empty, no mails are stored on the IMAP server
automatically

Fixes #574
2020-04-16 15:32:25 +02:00
FreeScout
276dff3ae1 Merge pull request #576 from ChrisRAoW/master
Fix for reply on notification e-mail not assigned to original conversion
2020-04-13 07:45:00 +05:45
ChrisRAoW
e1ed469ec9 Fix for reply on notification e-mail not assigned to original conversion
Mac mail (at least) removes elements that are set to display none when you're replying. Because the {#FS:****#} was in an hidden div it was removed, and freescout was not able anymore to relate the reply to the original conversation. Simply removing the display none fixes that.
2020-04-12 20:44:50 +02:00
FreeScout
d60ac945fc Merge pull request #573 from cloudron-io/invite-subject
Use getCompanyName() wrapper for fallback value
2020-04-12 17:18:22 +05:45
Johannes Zellner
82d0f81498 Use getCompanyName() wrapper for fallback value
Fixes #570
2020-04-12 12:24:03 +02:00
FreeScout
f176c1f117 Fix Undefined variable folder in FetchEmails.php 2020-04-03 04:11:12 -07:00
FreeScout
341f4c006f Merge branch 'master' of github.com:freescout-helpdesk/freescout into dist 2020-03-29 02:10:41 -07:00
FreeScout
a86721f992 v1.5.3 2020-03-29 02:09:57 -07:00
FreeScout
d50805da83 Add setting for conversation history in user notifications - closes #375 2020-03-28 22:07:54 -07:00
FreeScout
7532cec613 Merge pull request #548 from fvdm/feature-userhistory
Add setting for conversation history in user notifications
2020-03-29 10:30:38 +05:45
FreeScout
6ef4e44c88 Allow to exclude INBOX from IMAP folders 2020-03-28 21:33:24 -07:00
FreeScout
c147acedda Merge branch 'master' of github.com:freescout-helpdesk/freescout 2020-03-28 20:55:28 -07:00
FreeScout
b60c4e24e6 Merge pull request #547 from rosinghal/feature/imap-inbox-not-default
Feature/imap inbox not default
2020-03-29 09:40:03 +05:45
FreeScout
b4d8c82e04 Do not fetch from mailboxes with empty password 2020-03-28 20:44:51 -07:00
Franklin
4c197400da Whitespace fix 2020-03-24 14:23:23 +01:00
Franklin
b422c44603 Add config conv history in user notifications 2020-03-24 13:57:29 +01:00
Rohit Singhal
8fd7a5ad8f default folder to be INBOX 2020-03-20 12:20:30 +05:30
FreeScout
5cfcf77c32 Merge pull request #535 from fvdm/patch-1
Add option to include the last message in notifications
2020-03-16 09:36:18 +05:45
Franklin
e15a40f7d9 Roll back email_conv_history in user notifications 2020-03-14 10:49:16 +01:00
FreeScout
62905aa073 Merge pull request #538 from fvdm/patch-2
Add .editorconfig for consistent whitespace
2020-03-14 10:27:30 +05:45
Franklin
b98d3f7be2 Add .editorconfig for consistent whitespace 2020-03-13 17:21:42 +01:00
Franklin
1808a0473c Remove inconsistent whitespace 2020-03-13 17:15:57 +01:00
Franklin
1d8d609307 Fix ugly whitespace 2020-03-13 16:43:41 +01:00
Franklin
c8f9645eae Allow to include only the last message in user notifications 2020-03-13 16:40:19 +01:00
Franklin
0b83f75e14 Add option to include last message of conversation 2020-03-13 16:00:37 +01:00
Franklin
ee2199afce Allow to include only the last message 2020-03-13 15:57:00 +01:00
FreeScout
b7a3719815 Add vendor files to dist 2020-03-12 23:05:28 -07:00
FreeScout
2b7a5c31d4 Merge branch 'master' of github.com:freescout-helpdesk/freescout into dist 2020-03-12 23:03:14 -07:00
FreeScout
015c72292f v1.5.2 2020-03-12 23:02:29 -07:00
FreeScout
303619d060 jobs.send_reply_to_customer.send_previous_messages filter 2020-03-12 23:00:17 -07:00
FreeScout
219c8c0ccc Update Readme 2020-03-12 22:52:55 -07:00
FreeScout
d3158cc8a1 Fix The filename fallback must only contain ASCII characters - closes #533 2020-03-12 22:08:04 -07:00
FreeScout
d4c69004cc Merge branch 'master' of github.com:freescout-helpdesk/freescout into dist 2020-03-12 01:57:14 -07:00
FreeScout
c0cd027904 v1.5.1 2020-03-12 01:56:38 -07:00
FreeScout
12675a1586 Option to send full conversation history to customers - closes #447 2020-03-12 01:48:54 -07:00
FreeScout
a51d89f559 Merge branch 'master' of github.com:freescout-helpdesk/freescout 2020-03-09 04:04:51 -07:00
FreeScout
2c4d41f8da Merge pull request #520 from cloudron-io/user-create-args
Add commandline arguments to freescout:create-user
2020-03-09 16:49:33 +05:45
FreeScout
6491fc3ddd Do not log encoding conversion errors 2020-03-09 03:59:35 -07:00
Rohit Singhal
a51189e6f6 Removing INBOX as default IMAP folder 2020-03-09 08:07:12 +05:30
FreeScout
3bdee559e6 Add vendor files to dist 2020-03-07 20:08:44 -08:00
FreeScout
de67e11704 Merge branch 'master' of github.com:freescout-helpdesk/freescout into dist 2020-03-07 20:07:04 -08:00
FreeScout
180380339d v1.5.0 2020-03-07 20:06:33 -08:00
FreeScout
1d7be34787 APP_DOWNLOAD_ATTACHMENTS_VIA 2020-03-07 20:01:57 -08:00
Johannes Zellner
d8e3c1a390 Add commandline arguments for feescout:create-user for automation 2020-03-07 17:14:53 -08:00
FreeScout
c4bf136fbd Check max PHP version in the installer 2020-03-07 03:31:47 -08:00
FreeScout
dc567ea94f Merge pull request #518 from fvdm/patch-1
Remove trailing n from relative date minutes for Dutch systems
2020-03-07 15:59:58 +05:45
FreeScout
b4133dbb7e Secure attachments - closes #308 2020-03-07 02:02:03 -08:00
Franklin
3c8f2855bf Fix relative date for Dutch translation 2020-03-06 13:06:41 +01:00
FreeScout
9583a2a9e9 Merge branch 'master' of github.com:freescout-helpdesk/freescout into dist 2020-03-05 02:55:59 -08:00
FreeScout
37646b4f63 v1.4.12 2020-03-05 02:55:24 -08:00
FreeScout
96adf59413 Properly decode sender name - closes #516 2020-03-05 02:46:36 -08:00
FreeScout
6fadc6f4f8 Merge branch 'master' of github.com:freescout-helpdesk/freescout 2020-03-05 02:22:41 -08:00
FreeScout
4a2be8898d Improve autoresponders detection - closes #513 2020-03-05 02:22:19 -08:00
FreeScout
8bfbc93cf8 Show mailbox email in the thread CC 2020-03-05 02:09:48 -08:00
FreeScout
cb139b11ca Show only native languages in the language dropdown 2020-03-05 01:44:27 -08:00
FreeScout
e1e3ccc599 Polish language 2020-03-05 01:39:39 -08:00
FreeScout
00e7d0793a Save mailbox email as customer 2020-03-05 01:30:54 -08:00
FreeScout
6a0e2528db Merge pull request #508 from carsso/master
Updating French translations
2020-03-03 13:33:02 +05:45
Germain Carré
c612810a2a Updating French translations 2020-02-27 23:33:41 +01:00
FreeScout
21243fd7a0 Allow to disable users to prevent them from logging in 2020-02-21 21:53:51 -08:00
FreeScout
ca1b010529 Merge branch 'master' of github.com:freescout-helpdesk/freescout into dist 2020-02-18 00:52:07 -08:00
FreeScout
a2d7297382 v1.4.11 2020-02-18 00:51:28 -08:00
FreeScout
6052103ebf conversation.create_form.subject_append hook 2020-02-18 00:49:01 -08:00
FreeScout
383cbe953f Update dutch translation 2020-02-17 19:01:35 -08:00
FreeScout
75d20f7e0f Allow recipient name in the To field - closes #305 2020-02-16 23:05:15 -08:00
FreeScout
9fe7644f0a Merge branch 'master' of github.com:freescout-helpdesk/freescout 2020-02-16 22:27:06 -08:00
FreeScout
863c41d550 Merge pull request #488 from Qrious/multi-email-input
Fix tokenization of multiple emails on copy+paste of multiple emails
2020-02-17 12:11:50 +05:45
FreeScout
5280f71e15 Escape user name in This reply will go to the customer message 2020-02-16 22:23:48 -08:00
FreeScout
df7b0772c8 Allow admins to mute notifications for events not related directly to him/her 2020-02-16 21:13:05 -08:00
Sander Klock
4ea63506a5 Fix tokenization of multiple emails on copy+paste of string containing multiple emails 2020-02-16 16:57:33 +01:00
FreeScout
fae1253df6 Merge branch 'master' of github.com:freescout-helpdesk/freescout into dist 2020-02-15 22:01:55 -08:00
FreeScout
d9e074762b v1.4.10 2020-02-15 22:01:09 -08:00
FreeScout
096cd4f9b9 Command to logout users: freescout:logout-users 2020-02-15 19:10:55 -08:00
FreeScout
39f6c8959e Swedish language 2020-02-15 02:27:08 -08:00
FreeScout
3824bcb359 Concatenate multiple plain text parts on fetching emails 2020-02-15 00:40:13 -08:00
FreeScout
3b56ce55ed Caret style in conversation bulk actions 2020-02-14 03:17:42 -08:00
FreeScout
31b8c24b4b Ignore git folder when importing translations 2020-02-10 21:58:35 -08:00
FreeScout
a0b97b51c9 Show (no subject) when viewing conversation without a subject 2020-02-09 21:18:11 -08:00
FreeScout
f45925d34d Add IfModule to attachment .htaccess 2020-02-09 21:05:55 -08:00
FreeScout
90a34c1295 Fix placeholders in French translations - closess #469 2020-02-09 02:35:02 -08:00
FreeScout
42717759b6 Spanish translation 2020-02-09 02:29:55 -08:00
FreeScout
695ca73817 Merge branch 'master' of github.com:freescout-helpdesk/freescout into dist 2020-02-09 00:12:04 -08:00
FreeScout
f21a95940e v1.4.9 2020-02-09 00:11:21 -08:00
FreeScout
7fe21927c9 Force downloading attachments on Apache 2020-02-08 03:19:12 -08:00
FreeScout
8338777318 Notice on placeholders in translations 2020-02-08 03:03:27 -08:00
FreeScout
e2c1b65e9e Focus search input on view - closes #470 2020-02-08 02:58:40 -08:00
FreeScout
e4f397d593 Show user vars in mailbox signature and hide in Auto Reply - closes #458 2020-02-08 02:38:21 -08:00
FreeScout
c0893aa500 Hide admins from Assign list - closes #456 2020-02-06 02:52:06 -08:00
FreeScout
726d78d4f8 Show Assignee in custom folders - closes #465 2020-02-04 23:08:10 -08:00
FreeScout
918e31483b Merge branch 'master' of github.com:freescout-helpdesk/freescout into dist 2020-02-02 06:37:30 -08:00
FreeScout
54960a9a99 v1.4.8 2020-02-02 06:35:48 -08:00
FreeScout
71feae1ee1 Merge branch 'master' of github.com:freescout-helpdesk/freescout 2020-02-01 20:44:00 -08:00
FreeScout
317bf35c9c Merge pull request #459 from santibm/master
Feature request: adding images to mailbox signature #366 and showing remove button in main toolbar in desktop
2020-02-02 10:28:49 +05:45
FreeScout
73b8fa039f Fix utf subject inlowercase 2020-02-01 20:15:53 -08:00
SBM
8e1412c014 Showing remove button in main toolbar in desktop #454 2020-02-01 22:23:37 +01:00
SBM
8cc777013c Removing unused route for adding images to mailbox signature #366 2020-02-01 20:25:57 +01:00
SBM
750f98648d Changes for adding images to mailbox signature #366 2020-02-01 20:23:01 +01:00
SBM
995f36075a Feature request: adding images to mailbox signature #366 2020-02-01 10:24:34 +01:00
FreeScout
74a56142f6 Merge branch 'master' of github.com:freescout-helpdesk/freescout into dist 2020-01-28 22:42:29 -08:00
FreeScout
cd9fc3e5a3 v1.4.7 2020-01-28 22:41:58 -08:00
FreeScout
c8001a615e Return user in User::create function 2020-01-28 02:39:43 -08:00
FreeScout
7be3266543 Merge branch 'master' of github.com:freescout-helpdesk/freescout into dist 2020-01-25 05:35:32 -08:00
FreeScout
d0f013c536 1.4.6 2020-01-25 05:35:14 -08:00
FreeScout
d8f36cd716 Merge branch 'master' of github.com:freescout-helpdesk/freescout into dist 2020-01-25 05:30:36 -08:00
FreeScout
9718d42c13 v1.4.5 2020-01-25 05:30:09 -08:00
FreeScout
ed46dca3da bulk_actions.before_delete hook 2020-01-25 05:07:53 -08:00
FreeScout
07f40b5c15 Fix headers decoding issue 2020-01-25 04:30:15 -08:00
FreeScout
e004968328 Fix detecting bounced messages 2020-01-25 01:28:15 -08:00
FreeScout
4a71d6fa73 Process github api errors on System page - closes #449 2020-01-24 23:34:05 -08:00
FreeScout
b29db2c76c Merge branch 'master' of github.com:freescout-helpdesk/freescout into dist 2020-01-24 05:47:48 -08:00
FreeScout
a817e001db v1.4.4 2020-01-24 05:46:54 -08:00
FreeScout
35341a9caf Update French translations 2020-01-24 05:33:50 -08:00
FreeScout
7e469d6bea Do no escape person in getActionText 2020-01-24 00:04:42 -08:00
FreeScout
c1a5999471 Escape signature variables 2020-01-22 23:09:39 -08:00
FreeScout
9a193be6f3 Notice for Background Jobs in Status 2020-01-21 01:43:51 -08:00
FreeScout
9464f46bf6 Fix publishing modules translations 2020-01-21 00:36:49 -08:00
FreeScout
f24a12ef45 Merge pull request #440 from TimoStramann/patch-2
Update de.json
2020-01-21 11:00:22 +03:00
Timo Stramann
f36252ac87 Update de.json 2020-01-20 22:51:54 +01:00
FreeScout
2653bf49d0 Merge pull request #438 from santibm/master
Adding new filters to allow hooking menu items from third party modules
2020-01-20 15:15:45 +03:00
SBM
781b51ea88 Fix on adding new filters to allow hooking menu items from third party modules 2020-01-20 13:14:48 +01:00
SBM
36147e7b2f Adding new filters to allow hooking menu items from thrid party modules 2020-01-20 12:03:02 +01:00
FreeScout
8842a097ab Merge branch 'master' of github.com:freescout-helpdesk/freescout into dist 2020-01-19 08:50:08 -08:00
FreeScout
2a1445c060 v1.4.3 2020-01-19 08:49:33 -08:00
FreeScout
bd24a34f8f Merge branch 'master' of github.com:freescout-helpdesk/freescout 2020-01-19 08:44:58 -08:00
FreeScout
fcee9b2003 Add rememberCacheDriver to rememberable entities 2020-01-19 01:09:42 -08:00
FreeScout
923a2db2d0 Move calendar to the partial 2020-01-19 00:59:14 -08:00
FreeScout
59c2b6fa0f Merge pull request #434 from TimoStramann/master
Added German translation
2020-01-18 14:06:07 +03:00
Timo Stramann
9984c4453f Added German translation
Most strings translated into German
2020-01-18 11:55:15 +01:00
FreeScout
b439c8db3b Update readme 2020-01-17 20:55:15 -08:00
FreeScout
cb828d577e Fix Undefined variable cipher - closes #432 2020-01-17 11:02:06 -08:00
FreeScout
4b48841caa Merge branch 'master' of github.com:freescout-helpdesk/freescout into dist 2020-01-17 04:38:40 -08:00
FreeScout
adf422687a v1.4.2 2020-01-17 04:38:02 -08:00
FreeScout
3a99faa85c Fix In-Reply-To header in replies to customer - closes #428 2020-01-16 23:30:45 -08:00
FreeScout
e245659e5f Sort users alphabetically - closes #427 2020-01-16 22:41:48 -08:00
FreeScout
17d85512a2 Sort users alphabetically - closes #427 2020-01-16 00:08:45 -08:00
FreeScout
727d967823 German language 2020-01-15 23:47:20 -08:00
FreeScout
54a51d9d82 Merge branch 'master' of github.com:freescout-helpdesk/freescout 2020-01-15 23:35:22 -08:00
FreeScout
5a0289a4b6 Merge pull request #426 from santibm/master
Spaces in some conversation titles are replaced by underscores #420
2020-01-16 10:34:38 +03:00
FreeScout
790181a720 Merge pull request #425 from TimoStramann/patch-1
Adding German translation
2020-01-16 09:33:43 +03:00
SBM
a440b8d3bc Spaces in some conversation titles are replaced by underscores #420 2020-01-15 23:15:31 +01:00
Timo Stramann
e64025fb30 Adding German translation
German translation of all currently available strings
2020-01-15 22:39:37 +01:00
FreeScout
904d1650cd thread.opened hook 2020-01-14 23:54:37 -08:00
FreeScout
4765d96cec Year in footer 2020-01-14 23:17:50 -08:00
FreeScout
6a85c9588f Merge branch 'master' of github.com:freescout-helpdesk/freescout into dist 2020-01-14 00:52:58 -08:00
FreeScout
7a6157fd12 v1.4.1 2020-01-14 00:52:22 -08:00
FreeScout
f8cf6f9fb6 Save to the log only first failed send attempt - closes #413 2020-01-14 00:48:02 -08:00
FreeScout
2cd39eb5c9 findNonDeleted user function 2020-01-13 09:01:38 -08:00
FreeScout
f823d7527d Set has_attachments when replying 2020-01-13 00:59:19 -08:00
FreeScout
70732b7f94 Update readme 2020-01-12 04:01:32 -08:00
FreeScout
6bf9858c94 mailbox.before_delete hook 2020-01-10 23:41:40 -08:00
FreeScout
f46c9847ce addFloatingFlash function 2020-01-10 23:41:31 -08:00
FreeScout
7a6480a5a1 addFlashMessage helper function 2020-01-10 23:05:55 -08:00
FreeScout
6e1b95ff59 UserDeleted event params 2020-01-10 21:27:53 -08:00
FreeScout
faf39b0e9c deleteToFolder function for conversation 2020-01-10 21:15:50 -08:00
FreeScout
bae93001f0 Update readme 2020-01-10 21:15:04 -08:00
FreeScout
a55985b415 createUserThread function 2020-01-09 06:04:12 -08:00
FreeScout
794242f42f thread.meta hook 2020-01-09 04:24:17 -08:00
FreeScout
16846cfa26 Thread meta link style 2020-01-09 04:24:03 -08:00
FreeScout
a59e55642b Properly choose new thread in Subscribe 2020-01-08 09:48:02 -08:00
FreeScout
78b074499b Check all threads 2020-01-08 06:13:52 -08:00
FreeScout
83851ba366 Do not allow users delete themselve 2020-01-07 22:47:58 -08:00
FreeScout
740f684324 Logout deleted users 2020-01-07 22:44:29 -08:00
FreeScout
f5240ed605 Fix view.blade.php html 2020-01-07 10:44:28 -08:00
FreeScout
1d32c0f2cd Show mailbox fetching status 2020-01-07 05:19:59 -08:00
FreeScout
a0d251eb9a Merge branch 'master' of github.com:freescout-helpdesk/freescout into dist 2020-01-07 02:12:00 -08:00
FreeScout
6ecda5b99b v1.4.0 2020-01-07 02:11:22 -08:00
FreeScout
61d4c735b3 Conversations I'm following search bookmark - closes #350 2020-01-07 02:08:06 -08:00
FreeScout
d083f4bdf9 Followed conversations search bookmark 2020-01-07 01:11:57 -08:00
FreeScout
3175fd6518 View followed conversations in the search - closes #406 2020-01-07 00:51:08 -08:00
FreeScout
9586c67d53 Send emails separately to each recipient checkbox on create 2020-01-07 00:35:57 -08:00
FreeScout
8db93a4ee4 conversation.created hook 2020-01-06 02:00:08 -08:00
FreeScout
585f35546f changeUser function 2020-01-04 01:00:43 -08:00
FreeScout
4eaadab2bc thread.created hook 2020-01-04 00:38:47 -08:00
FreeScout
7e3781a662 Automatically cast Thread meta to array 2020-01-03 23:37:47 -08:00
FreeScout
286ac988c7 Empty Trash button - closes #263 2020-01-03 02:16:33 -08:00
FreeScout
deaa8a47be Fix uploaded file position in reply form 2020-01-03 01:08:44 -08:00
FreeScout
b1d0ae9fee Delete single conversation forever 2020-01-03 01:03:36 -08:00
FreeScout
d69a5bfcda Update fr translation 2020-01-02 23:45:51 -08:00
FreeScout
b63dfb136f Remove dot before @ in emails 2020-01-02 23:42:49 -08:00
FreeScout
aa58d5fe75 Merge branch 'master' of github.com:freescout-helpdesk/freescout 2020-01-02 23:29:28 -08:00
FreeScout
aab1c3e85b changeStatus function for conversation 2020-01-02 23:22:39 -08:00
FreeScout
cbd00ca192 Update forward and move icons 2020-01-02 05:55:26 -08:00
FreeScout
3e4392d4ad USER_UNASSIGNED const 2019-12-31 04:19:58 -08:00
FreeScout
f5d85b8594 Style for reply label 2019-12-31 04:19:41 -08:00
FreeScout
b1966a2a85 Pass trigger to modals 2019-12-31 04:19:21 -08:00
FreeScout
0516ebaa57 Merge pull request #400 from wevothere120/master
Fix #374 by ignoring > in local part of mail regex
2019-12-30 21:12:47 +03:00
wevothere120
679fa7546c OR operator wasn't actually necessary in a36228807c 2019-12-30 18:57:14 +01:00
wevothere120
e76891b280 fixes freescout-helpdesk/freescout#374
Although in some cases it is allowed to use ">" in local part of email address, it is not very common, so it shouldn't break anything. Tested on bunch of threads and found no issues
2019-12-30 18:56:53 +01:00
FreeScout
4d5da851ab Default label color 2019-12-29 23:48:38 -08:00
FreeScout
d8c848cfae Update readme 2019-12-28 05:44:21 -08:00
FreeScout
2df4c024f4 Merge branch 'master' of github.com:freescout-helpdesk/freescout into dist 2019-12-28 04:00:17 -08:00
FreeScout
24d4971abe v1.3.19 2019-12-28 03:59:25 -08:00
FreeScout
cc32cc8257 .col classes 2019-12-27 23:38:32 -08:00
FreeScout
bd52e9c72d conv-sidebar-block on mobile 2019-12-27 23:08:27 -08:00
FreeScout
40b62be293 conversation.follow JS hook 2019-12-27 22:31:40 -08:00
FreeScout
3db52a6c41 isAjaxSuccess function 2019-12-27 21:24:48 -08:00
FreeScout
43f7ebb225 Sidebar block style 2019-12-27 01:04:18 -08:00
FreeScout
bd070a8af9 Sort mailbox users by full name by defaul 2019-12-27 01:03:54 -08:00
FreeScout
8e379b14f1 Sort mailbox users by full name by default 2019-12-26 04:38:04 -08:00
FreeScout
2d0cb64ec3 Rename conversation.after_customer hook into conversation.after_prev_convs 2019-12-26 04:12:23 -08:00
FreeScout
6291f48263 Conversation actions bottons hooks 2019-12-26 00:57:36 -08:00
FreeScout
f103bda6fe Icons for conversation actions dropdown 2019-12-26 00:53:46 -08:00
FreeScout
7ea54b6f03 Following conversations 2019-12-25 05:17:17 -08:00
FreeScout
f4d04f6691 Fix starring conversations 2019-12-23 05:54:36 -08:00
FreeScout
a2efc65226 Merge branch 'master' of github.com:freescout-helpdesk/freescout into dist 2019-12-22 01:38:20 -08:00
FreeScout
c5117c7898 v.1.3.18 2019-12-22 01:37:34 -08:00
FreeScout
86761c405c Fix Row size too large error 2019-12-22 01:36:45 -08:00
FreeScout
4fc419ba74 Maximum password length notice 2019-12-22 01:21:21 -08:00
FreeScout
8686012302 Fix Row size too large error 2019-12-22 01:11:21 -08:00
FreeScout
90f3f4b56f Update readme 2019-12-21 08:50:18 -08:00
FreeScout
19edef364f Merge branch 'master' of github.com:freescout-helpdesk/freescout into dist 2019-12-21 05:02:02 -08:00
FreeScout
ce307ddc45 1.3.17 2019-12-21 05:01:24 -08:00
FreeScout
948de91102 Update layout translation strings 2019-12-21 02:19:24 -08:00
FreeScout
ab751c3b27 Update ru translation 2019-12-21 02:19:12 -08:00
FreeScout
d01df11a21 Folder hooks 2019-12-20 01:41:06 -08:00
FreeScout
0e4c9efdbe Limit folder name width 2019-12-19 23:33:20 -08:00
FreeScout
80438e991c Folder hooks 2019-12-19 23:06:34 -08:00
FreeScout
d0e224dbe1 requiredModules parameter for modules 2019-12-19 01:18:52 -08:00
FreeScout
53138e405e Fix Row size too large error - closes #393 2019-12-18 23:02:26 -08:00
FreeScout
a3a1e0d621 Merge branch 'master' of github.com:freescout-helpdesk/freescout into dist 2019-12-18 09:58:42 -08:00
FreeScout
92efaab611 v1.3.16 2019-12-18 09:58:13 -08:00
FreeScout
a87156690b Update nl translation 2019-12-18 05:02:11 -08:00
FreeScout
fa01192bd3 layout hooks 2019-12-18 04:58:54 -08:00
FreeScout
0c2d9900f3 Upload file helper functions 2019-12-18 04:58:41 -08:00
FreeScout
ebd34d0d0a Merge branch 'master' of github.com:freescout-helpdesk/freescout into dist 2019-12-16 23:44:21 -08:00
FreeScout
f3ea9bcb47 v1.3.15 2019-12-16 23:43:04 -08:00
FreeScout
33c5f74bf3 Do not allow to send empty reply 2019-12-16 23:40:30 -08:00
FreeScout
babb1f3956 isNewConversation js function 2019-12-16 10:06:20 -08:00
FreeScout
c0b48208e6 conversation.create_form.after_subject hook 2019-12-16 10:05:48 -08:00
FreeScout
b00b830f21 mailboxes.menu_current_route filter 2019-12-16 00:44:12 -08:00
FreeScout
a24c56b527 Fix customers ajax search pagination 2019-12-16 00:43:11 -08:00
FreeScout
bd1f4b06bc Label styles 2019-12-13 21:52:40 -08:00
FreeScout
c3cbeebf91 Add identifier to queue:work command to void conflicts with other FreeScout instances on the same server - closes #387 2019-12-13 21:52:23 -08:00
FreeScout
bba3f071ee Text Before The Reply option for the mailbox 2019-12-11 00:37:05 -08:00
FreeScout
eaf5bb245b Text Before The Reply option for the mailbox 2019-12-10 02:04:27 -08:00
FreeScout
52bc01dede Create customer from Change customer dialog - closes #49 2019-12-10 02:00:12 -08:00
FreeScout
1b3020d99a Text Before The Reply option for the mailbox - closes #349 2019-12-10 00:21:01 -08:00
FreeScout
046f0ce79d Remove user variables from the mailbox signature - closes #383 2019-12-09 23:12:58 -08:00
FreeScout
79c40bc505 Fix starred conversations counter 2019-12-09 22:51:49 -08:00
FreeScout
c822777ed3 Add vendor files to dist 2019-12-09 05:50:48 -08:00
FreeScout
29ebb5ad72 Merge branch 'master' of github.com:freescout-helpdesk/freescout into dist 2019-12-09 05:49:42 -08:00
FreeScout
4cdf9d9b63 v1.3.14 2019-12-09 05:48:23 -08:00
FreeScout
120f81e3f5 Fetch all bodies of emails with multiple HTML parts - closes #381 2019-12-09 05:31:54 -08:00
FreeScout
0c70621935 Remove trailing dots from emails - closes #379 2019-12-09 02:05:55 -08:00
FreeScout
9efa70a0ee Set connection timeout when downloading modules 2019-12-08 11:17:03 -08:00
FreeScout
b5dd14758b Merge branch 'master' of github.com:freescout-helpdesk/freescout into dist 2019-12-08 09:01:36 -08:00
FreeScout
1cd8881088 v1.3.13 2019-12-08 09:00:46 -08:00
FreeScout
e0654d8e08 ru language 2019-12-08 09:00:34 -08:00
FreeScout
b30ffc19cd Remove modals from DOM on hide 2019-12-06 22:06:19 -08:00
FreeScout
3f0b64775f Dashboard dates size 2019-12-06 04:12:50 -08:00
FreeScout
02bfc295e6 Do not add module translation strings existing in the app 2019-12-06 02:56:51 -08:00
FreeScout
fcf957db9c Update readme 2019-12-06 02:02:42 -08:00
FreeScout
fe62c7fcd4 Add nl language 2019-12-06 02:01:53 -08:00
FreeScout
a15e87f23c Add ru language 2019-12-06 01:57:42 -08:00
FreeScout
4375c1ecd3 Allow translation strings in different case 2019-12-06 01:44:12 -08:00
FreeScout
d8d8ea3bd0 Revise translation strings 2019-12-06 01:28:22 -08:00
FreeScout
613c888d47 Fix counting changed translations 2019-12-06 01:11:16 -08:00
FreeScout
4c665f3749 Fix counting translations 2019-12-06 00:45:40 -08:00
FreeScout
307fe595f0 Fix importing jsons of locales with dashes 2019-12-05 23:17:12 -08:00
FreeScout
341d4ebf24 Fix importing translations 2019-12-05 23:06:35 -08:00
FreeScout
3adde31a47 Allow translation strings in different case 2019-12-05 10:00:44 -08:00
FreeScout
6acd19977c Revise translation strings 2019-12-05 09:59:46 -08:00
FreeScout
df9bddb85f Fix js messages translation - closes #363 2019-12-05 01:03:41 -08:00
FreeScout
3d6928fcdc Fix last reply date in conversation list 2019-12-04 23:29:43 -08:00
FreeScout
f242090f8d When importing translations remove nonexisting _app translations 2019-12-04 01:13:01 -08:00
FreeScout
dd071d4926 JS filters and scrolling to reply area 2019-12-03 01:09:33 -08:00
FreeScout
e38ccdee96 Sortable panel 2019-12-02 06:25:01 -08:00
FreeScout
7da26f92bf Catch exception when sending translation 2019-11-26 22:43:14 -08:00
FreeScout
14c04c8ce1 Increment retry interval in case SMTP server is not available 2019-11-26 21:49:16 -08:00
FreeScout
5e928270bb Merge branch 'master' of github.com:freescout-helpdesk/freescout into dist 2019-11-25 09:24:25 -08:00
FreeScout
9661a938c5 v1.3.12 2019-11-25 09:23:49 -08:00
FreeScout
6ca806f733 Update sidebar folders in real-time 2019-11-25 09:20:23 -08:00
FreeScout
ebb8a1c60f Auto refresh conversations - closes #285 2019-11-25 06:19:36 -08:00
FreeScout
01d8d8b34d Update sidebar folders in real-time 2019-11-25 02:48:23 -08:00
FreeScout
17f280708e Dinamically load new messages, assignee and status when viewing the conversation 2019-11-25 01:23:16 -08:00
FreeScout
3a0e3b780a Fix styles when conversation top block is visible 2019-11-24 00:13:36 -08:00
FreeScout
3e1ca23348 Fix eventy null argument issue 2019-11-23 23:08:13 -08:00
FreeScout
22317cd092 Move conversation by entering the traget mailbox email - closes #367 2019-11-23 22:46:13 -08:00
FreeScout
9410d282cc When discarding a new conversation being created from thread return to original conversation 2019-11-23 03:13:43 -08:00
FreeScout
3e732ddbe6 Merge branch 'master' of github.com:freescout-helpdesk/freescout into dist 2019-11-17 05:20:02 -08:00
FreeScout
e4a7c2713f v1.3.11 2019-11-17 05:19:20 -08:00
FreeScout
32e40ed930 Fallback to additional freescout API url if can not connect to the main 2019-11-17 05:18:06 -08:00
FreeScout
1406b3566a conversations_table.after_subject hook 2019-11-17 03:10:08 -08:00
FreeScout
7022a5a992 conversation.view.start hook 2019-11-17 03:09:52 -08:00
FreeScout
ef98cec45a JS hooks 2019-11-17 01:10:16 -08:00
FreeScout
c0477f52f5 Take default settings values into account when saving options 2019-11-16 01:03:34 -08:00
FreeScout
111a0dcdca Pass prev_user_id to conversation.user_changed hook 2019-11-16 01:02:52 -08:00
FreeScout
0113623294 Rename conversation.status_changed_by_user hook into conversation.status_changed 2019-11-15 00:41:47 -08:00
FreeScout
c73857425a Rename conversation.status_changed_by_user hook into conversation.status_changed 2019-11-15 00:40:38 -08:00
FreeScout
a53374f94f conversation.status_changed hook 2019-11-15 00:32:24 -08:00
FreeScout
d0f771a78e Update readme features 2019-11-14 08:46:03 -08:00
FreeScout
0682433113 Send only support agent reply without full conversation history in emails to customers - closes #365 2019-11-14 00:17:50 -08:00
FreeScout
9f84983680 Update sidebar hamburger style 2019-11-13 23:40:07 -08:00
FreeScout
025b1e4a61 Do not show deleted users in the users dropdown - closes #364 2019-11-13 23:36:28 -08:00
FreeScout
5fbcf19389 Log fetch exceptions to activity log 2019-11-13 23:30:20 -08:00
FreeScout
0b4f4f915a Update mobile hamburger style 2019-11-13 06:18:29 -08:00
FreeScout
9c7cce6d07 Do not throw exception when parsing date on fetching 2019-11-13 05:29:02 -08:00
FreeScout
fd3ae64d9d Fix Conversion from cp-850 to UTF-8 is not allowed - closes #360 2019-11-13 04:41:17 -08:00
FreeScout
ece4e9f3e1 Fix checking module symlnk 2019-11-09 01:51:46 -08:00
FreeScout
fda982c7d1 Merge branch 'master' of github.com:freescout-helpdesk/freescout into dist 2019-11-08 23:23:22 -08:00
FreeScout
a4acf8caa7 v1.3.10 2019-11-08 23:22:50 -08:00
FreeScout
da08b93e25 Update readme 2019-11-08 23:17:58 -08:00
FreeScout
1f8229ca5c Mobile app features 2019-11-08 23:08:51 -08:00
FreeScout
4afdbb94cf Mobile app features 2019-11-07 00:45:01 -08:00
FreeScout
d591ec05c0 Switch helpdesk URL 2019-11-02 22:38:41 -07:00
FreeScout
9c971a0387 On update remove _tmp folders 2019-11-01 01:22:57 -07:00
FreeScout
e78d935a54 Merge branch 'master' of github.com:freescout-helpdesk/freescout into dist 2019-11-01 00:35:04 -07:00
FreeScout
1304f59bef v1.3.9 2019-11-01 00:34:09 -07:00
FreeScout
7a1aa3fb2a Allow to deactivate module license 2019-11-01 00:27:31 -07:00
FreeScout
712fd47880 Prevent public folder issue when activating modules 2019-10-31 03:43:21 -07:00
FreeScout
802c5cf20d Fix Message body is empty error - closes #320 2019-10-31 03:12:05 -07:00
FreeScout
8d2036636f Fix Wrong charset conversion from 1252 - closes #351 2019-10-31 01:18:36 -07:00
FreeScout
b0923098e4 Do not kill background workers of other laravel projects - closes #340 2019-10-31 00:50:51 -07:00
FreeScout
9673871c48 Checkout files in update.sh 2019-10-14 00:18:59 -07:00
FreeScout
d08d2ab786 Fix job_title and phone case in vars template 2019-10-14 00:08:57 -07:00
FreeScout
47608f26d5 Merge branch 'master' of github.com:freescout-helpdesk/freescout into dist 2019-10-14 00:01:27 -07:00
FreeScout
6dee385660 v1.3.8 2019-10-14 00:00:37 -07:00
FreeScout
ec7d82d663 Improve user photoUrl variable in mailbox signature 2019-10-13 23:59:00 -07:00
FreeScout
567b47f793 Fix customer avatar path in subdirectory 2019-10-13 23:57:32 -07:00
FreeScout
f2603c030d Merge pull request #348 from frommMoritz/enhancement/more-fields-in-signature
Photo URL as Variable in signature
2019-10-14 09:44:54 +03:00
Moritz Fromm
2d24ea0e43 Add photoUrl variable as signature template
Close #281
2019-10-11 23:10:41 +02:00
Moritz Fromm
7f70f51c34 Return absolute URL from user->getPhotoUrl()
Ref #281
2019-10-11 23:04:18 +02:00
FreeScout
a5c3424d17 Merge pull request #347 from frommMoritz/enhancement/auto-detect-links
Detect links inside the E-Mail and convert them to html links
2019-10-11 09:03:21 +03:00
FreeScout
9cb3d2fde6 Merge pull request #346 from frommMoritz/enhancement/no-previous-spam
Do not show spam mails in previous conversations
2019-10-11 08:58:39 +03:00
FreeScout
8526ba4d04 Improve new variables in mailbox signature 2019-10-10 22:57:22 -07:00
FreeScout
ffcd58ac46 Merge pull request #345 from frommMoritz/enhancement/more-fields-in-signature
More fields in signature
2019-10-11 08:19:16 +03:00
Moritz Fromm
1d02f1362c Detect links inside the E-Mail and convert them to html links
The code used was released under the public domain by @jasny
https://gist.github.com/jasny/2000705

Close #341
2019-10-11 00:29:35 +02:00
Moritz Fromm
278a636398 Do not show spam mails in previous conversations
Close #338
2019-10-10 21:47:12 +02:00
Moritz Fromm
831ca7c3cb Add new variables to composing ui, including translations
Close #281
2019-10-10 20:50:27 +02:00
Moritz Fromm
5604cf1356 Add more fields in signature
user.jobTitle is being replaced with the jobTitle of the user
user.phone is being replaced with the phone of the user
user.email is being replaced with the email of the user
mailbox.fromName is being replaced with the senders name of the mailbox

Ref #281
2019-10-10 18:44:14 +02:00
FreeScout
b339b89c4b Merge pull request #344 from frommMoritz/enhancement/error-free-installation
Fix undefined variable envConfig
2019-10-10 19:42:39 +03:00
Moritz Fromm
cca24c8cbd Set maxlength for DB Password input to 50
Ref #343
2019-10-10 17:43:44 +02:00
Moritz Fromm
67cc30305b Retrieve envConfig in EnvironmentController
Ref #343
2019-10-10 17:31:05 +02:00
FreeScout
53102be531 Merge branch 'master' of github.com:freescout-helpdesk/freescout into dist 2019-10-05 23:18:00 -07:00
FreeScout
6b85d2398c v1.3.7 2019-10-05 23:17:32 -07:00
FreeScout
7fd5ee818a Auto Bcc for mailbox - closes #59 2019-10-05 23:15:05 -07:00
FreeScout
04f149c072 Updated pt-PT translation 2019-10-05 22:23:15 -07:00
FreeScout
c3edfd8acf Fix attachment names 2019-10-05 22:19:01 -07:00
FreeScout
9a7fc7c65c Merge pull request #332 from TWithers/attachment_name
Slugified attachment file names
2019-09-18 14:33:06 +03:00
Tim Withers
cc131cbf60 Slugified attachment file names to remove adverse interaction in browser urls. 2019-09-17 09:28:44 -07:00
FreeScout
2c4e415a66 Merge branch 'master' of github.com:freescout-helpdesk/freescout into dist 2019-09-06 05:23:52 -07:00
FreeScout
9bc4c3a210 v1.3.6 2019-09-06 05:23:00 -07:00
FreeScout
b9198e5b28 Fix conversations pagination - closes #315 2019-09-06 03:57:08 -07:00
FreeScout
67a5c44d06 Replace mailbox password with asterisks in HTML 2019-09-06 01:12:54 -07:00
FreeScout
39485f692c Log error if can not save vars.js 2019-09-06 00:02:15 -07:00
FreeScout
6a7c2dd778 Show preview of the full message for the thread in Show Original modal 2019-09-05 07:47:12 -07:00
FreeScout
20750ebddc Fetch emails with empty Message-ID 2019-09-05 05:07:11 -07:00
FreeScout
b8cbcb8619 Fetch emails with empty body 2019-09-05 05:01:36 -07:00
FreeScout
37fb2b1fb3 Check if outgoing port is open when testing connection 2019-09-05 04:02:33 -07:00
FreeScout
6950394054 Show mailbox email in mailbox settings sidebar 2019-09-05 03:39:40 -07:00
FreeScout
a0ee00bc2a Add target _blank to thread content only 2019-09-05 02:48:05 -07:00
FreeScout
dd58bdc545 Fetch emails with empty Message-ID - closes #311 2019-09-05 02:40:17 -07:00
FreeScout
67d46cda28 Update readme 2019-09-05 01:21:59 -07:00
FreeScout
06e04e1333 Show error message on updating modules 2019-08-10 09:11:57 -07:00
FreeScout
e8b745384c Prevent saving messages with empty body when detecting reply body 2019-08-10 00:11:38 -07:00
FreeScout
5397175314 Merge branch 'master' of github.com:freescout-helpdesk/freescout into dist 2019-08-07 11:34:44 -07:00
FreeScout
62636d73dc v1.3.5 2019-08-07 11:33:51 -07:00
FreeScout
374498b445 Fix app.force_https option 2019-08-07 11:29:06 -07:00
FreeScout
d63bfacc10 Fix ajax URL in subdirectory installations 2019-08-07 11:05:22 -07:00
FreeScout
9d697647c3 Merge branch 'master' of github.com:freescout-helpdesk/freescout into dist 2019-08-03 04:56:49 -07:00
FreeScout
e674b71081 Return tools/update.sh script 2019-08-03 04:53:56 -07:00
FreeScout
2b9e94b596 Merge branch 'master' of github.com:freescout-helpdesk/freescout into dist 2019-08-03 04:39:40 -07:00
FreeScout
3411683e47 v1.3.4 2019-08-03 04:38:58 -07:00
FreeScout
e2ca7d73a6 Do not show own conversation views in the conversation list 2019-08-02 11:53:33 -07:00
FreeScout
f2f5a9c488 Fix saving user view with UT8 name - closes #303 2019-08-02 06:30:32 -07:00
FreeScout
b0063d2c2e Fix utf8 user/customer initials 2019-08-02 06:29:20 -07:00
FreeScout
c55162e745 Fix app.force_https option 2019-08-02 05:16:21 -07:00
FreeScout
7e590b2179 Merge branch 'master' of github.com:freescout-helpdesk/freescout into dist 2019-07-30 06:51:57 -07:00
FreeScout
d157e702c1 v1.3.3 2019-07-30 06:49:09 -07:00
FreeScout
5681f4b74a Show users who are viewing conversation 2019-07-30 06:43:32 -07:00
FreeScout
2344917ce7 Update styles 2019-07-30 06:07:29 -07:00
FreeScout
e42ed6f581 Search by customers 2019-07-30 01:45:34 -07:00
FreeScout
3633bb68d7 Truncate long mailbox emails in the list 2019-07-30 01:36:54 -07:00
FreeScout
c178a7890e Thread date as hyperlink 2019-07-30 01:02:51 -07:00
FreeScout
7fea640a84 Show users who are viewing conversation 2019-07-30 00:28:31 -07:00
FreeScout
dea9c2e998 Merge branch 'master' into collision_detection 2019-07-28 00:14:18 -07:00
FreeScout
53a97f07b8 Merge branch 'master' of github.com:freescout-helpdesk/freescout into dist 2019-07-27 09:07:20 -07:00
FreeScout
e0ceb2bcd7 v1.3.2 2019-07-27 09:06:39 -07:00
FreeScout
f57611c1c9 Conversation after subject hook 2019-07-27 06:30:04 -07:00
FreeScout
b5ab58790a Hide cc trigger in note 2019-07-27 06:14:27 -07:00
FreeScout
7c5ca832e8 Fix json encoding non-latin symbols 2019-07-27 06:07:04 -07:00
FreeScout
491d68088e jsonEncodeUtf8() helper function 2019-07-27 05:51:34 -07:00
FreeScout
c478556c67 Search filters 2019-07-27 05:51:05 -07:00
FreeScout
83d5b26922 nl2brDouble helper function 2019-07-27 00:03:35 -07:00
FreeScout
4810cea1ab Conversation thread hooks 2019-07-26 21:58:29 -07:00
FreeScout
73657915a3 Helper functions 2019-07-26 21:58:02 -07:00
FreeScout
cceb140eb1 Add remove format button to the default editor 2019-07-26 00:10:42 -07:00
FreeScout
f147b4ef5f Fix creating Phone conversation without draft 2019-07-25 23:49:25 -07:00
FreeScout
102c1fcd96 Do not try to send email to customer for Phone conversations - closes #296 2019-07-25 23:45:04 -07:00
FreeScout
48e89b36c2 New reply separator 2019-07-25 23:26:08 -07:00
FreeScout
d1386ee8f3 Move conversation feature 2019-07-25 23:01:03 -07:00
FreeScout
1c32dad7d5 Update readme 2019-07-25 04:05:39 -07:00
FreeScout
362e9cf1e6 Check mailbox when fetching replies 2019-07-24 23:58:00 -07:00
FreeScout
d13640c466 Fix cc trigger position when forwarding 2019-07-24 23:34:15 -07:00
FreeScout
36ace2bb7e If customer without name show first part of email in profile 2019-07-24 22:51:16 -07:00
FreeScout
533a482d2c Merge branch 'master' of github.com:freescout-helpdesk/freescout into dist 2019-07-24 22:14:01 -07:00
FreeScout
14cbb06bdb v1.3.1 2019-07-24 22:13:06 -07:00
FreeScout
c2fb36a6d1 Optimize self-updating 2019-07-24 22:11:42 -07:00
FreeScout
0888a08c12 Merge branch 'master' of github.com:freescout-helpdesk/freescout into dist 2019-07-24 05:46:07 -07:00
FreeScout
8a6c81c607 Optimize self-updating 2019-07-24 05:35:20 -07:00
FreeScout
90bd50c38e Fix UL/OL in summernote editor 2019-07-24 05:13:34 -07:00
FreeScout
aad11d5d76 Redesign floating alerts 2019-07-24 05:03:29 -07:00
FreeScout
b9c140160c Show assignee or status change in note 2019-07-24 03:31:00 -07:00
FreeScout
497efafabf Redesign - customer in conversation on mobile 2019-07-24 03:26:31 -07:00
FreeScout
3e78fdc737 Redesign - blockquotes 2019-07-24 03:10:00 -07:00
FreeScout
a8b045d95b Fix icon position in floating message 2019-07-24 03:02:01 -07:00
FreeScout
ab9c5f68b8 Change logs route as on some hostings /logs/ not allowed 2019-07-24 02:46:28 -07:00
FreeScout
dc2ffe6393 Fix cc/bcc trigger position 2019-07-24 01:29:26 -07:00
FreeScout
7807a68a74 Allow to specify fetching period 2019-07-23 00:04:36 -07:00
FreeScout
99d11db2ed Fix error fetching emails from Office365 2019-07-22 23:34:01 -07:00
FreeScout
e1346ce833 Redesign modules list 2019-07-22 22:18:10 -07:00
FreeScout
a4e0fc66b4 Redesign modules list 2019-07-22 12:10:46 -07:00
FreeScout
046a00aaa0 Redesign modules list 2019-07-22 10:57:46 -07:00
FreeScout
08fe70bd69 Redesign modules list 2019-07-22 10:53:11 -07:00
FreeScout
df9b151d98 Update readme 2019-07-22 07:05:52 -07:00
FreeScout
ba12b17e94 Add vendor files to dist 2019-07-22 07:01:56 -07:00
FreeScout
911d18ed31 Merge branch 'master' of github.com:freescout-helpdesk/freescout into dist 2019-07-22 06:59:51 -07:00
FreeScout
b16e61af1a v1.3.0 2019-07-22 06:59:11 -07:00
FreeScout
41ad6bf3e0 Phone conversations 2019-07-22 06:56:01 -07:00
FreeScout
c16916455d Add native PHP mail() function support for swiftmailer 2019-07-22 02:39:52 -07:00
FreeScout
83376e0eac Phone conversations 2019-07-21 23:39:23 -07:00
FreeScout
95c2e1fea9 Select2 for Cc, Bcc, to_email 2019-07-16 05:52:09 -07:00
FreeScout
b38e0a4938 Send new conversation to multiple customers 2019-07-16 02:38:06 -07:00
FreeScout
5a3b15abcb Ajax suggest for recipient 2019-07-16 00:36:51 -07:00
FreeScout
e28ad0cc33 Fix MySQL isnt in GROUP BY error 2019-07-14 22:34:06 -07:00
FreeScout
9e2e10f7fb Merge branch 'master' of github.com:freescout-helpdesk/freescout into dist 2019-07-13 22:12:37 -07:00
FreeScout
06f9842a3a v1.2.6 2019-07-13 22:11:49 -07:00
FreeScout
d477b34d27 Do not allow to open app at /public/ 2019-07-12 20:51:45 -07:00
FreeScout
999f2ab3b0 Do not allow to open app at /public/ 2019-07-12 13:49:52 -07:00
FreeScout
99f5f4a2ad Save attachments when creating a new conversation - closes #289 2019-07-12 07:31:23 -07:00
FreeScout
5d79e3c833 Forward attachmets - closes #72 2019-07-12 06:56:07 -07:00
FreeScout
29f1f86f03 Search filters 2019-07-12 03:47:12 -07:00
FreeScout
7ea5f15371 Search filters 2019-07-12 02:52:11 -07:00
FreeScout
a7fd5288a1 Add vendor files to dist 2019-07-09 02:30:13 -07:00
FreeScout
3c0c61cb97 Merge branch 'master' of github.com:freescout-helpdesk/freescout into dist 2019-07-09 02:26:43 -07:00
FreeScout
771e9cd92b v1.2.5 2019-07-09 02:25:31 -07:00
FreeScout
e4548ac167 Fix The specified charset is not supporte error in Microsoft mailboxes - closes #176 2019-07-09 02:06:28 -07:00
FreeScout
c5e28eea7a Fixed not applying mailbox mail config 2019-07-09 01:10:27 -07:00
FreeScout
a0e187d1c7 Update vars.js only if content changed to prevent minified file rebuild 2019-07-08 21:40:03 -07:00
FreeScout
650c9029e9 Show creator of the new conversation draft 2019-07-08 06:33:37 -07:00
FreeScout
611cb37878 Show user status in profile and in the dropdown 2019-07-08 06:04:02 -07:00
FreeScout
2d54d40149 Optimize DB queries on conversation page 2019-07-08 03:41:25 -07:00
FreeScout
58493c77c1 Allow to send ougoing emails from SMTP server without login and password 2019-07-08 02:51:02 -07:00
FreeScout
78f28e8ed3 Update vars.js only if content changed to prevent minified file rebuild 2019-07-08 02:48:50 -07:00
FreeScout
5625442913 Do not regenerate vars on Setting save 2019-07-08 02:27:18 -07:00
FreeScout
6961d8d9ac Set editor buttons height 2019-07-06 22:13:48 -07:00
FreeScout
24b36271fe Hide todos 2019-07-06 22:12:56 -07:00
FreeScout
0bb3ec0d02 Ignore false IMAP errors 2019-07-06 02:13:40 -07:00
FreeScout
53ba824106 Ignore false IMAP errors - closes #270 2019-07-06 00:12:14 -07:00
FreeScout
396942fd17 Fix foreach issue in Webklex/IMAP/Client.php in getFolder() 2019-07-05 04:52:27 -07:00
FreeScout
8a92c6c44e Merge branch 'master' of github.com:freescout-helpdesk/freescout into dist 2019-07-05 03:20:40 -07:00
FreeScout
0151b7af4f v1.2.4 2019-07-05 03:19:50 -07:00
FreeScout
06ccb07c09 Fetch emails from custom IMAP folders - closes #206 2019-07-05 03:18:15 -07:00
FreeScout
25a00f5585 New email reply separator 2019-07-04 23:56:50 -07:00
FreeScout
2b0156fb13 Fix vars js issue 2019-07-04 23:51:18 -07:00
FreeScout
88aac4accf Do not force clear cache on Status page queue:work is not running 2019-07-04 23:46:04 -07:00
FreeScout
171be5630c Note should always keep conversation status 2019-07-04 23:31:31 -07:00
FreeScout
c4b6011dd9 Fix wrong assignee on reply 2019-07-04 23:22:54 -07:00
FreeScout
b90e68f23c Respect Users are allowed to edit notes/replies setting 2019-07-04 22:46:38 -07:00
FreeScout
61fdf8150b Add vendor files to dist 2019-07-04 07:35:30 -07:00
FreeScout
09ffb53bed Merge branch 'master' of github.com:freescout-helpdesk/freescout into dist 2019-07-04 07:32:57 -07:00
FreeScout
a0ee0a7387 Update composer.json 2019-07-04 07:32:38 -07:00
FreeScout
5f048f67bb Merge branch 'master' of github.com:freescout-helpdesk/freescout into dist 2019-07-04 07:03:43 -07:00
FreeScout
6b8a915609 Update composer.json - fix packages versions 2019-07-04 07:02:14 -07:00
FreeScout
d6aad6f97e Merge branch 'master' of github.com:freescout-helpdesk/freescout into dist 2019-07-04 06:53:39 -07:00
FreeScout
38485396ff v1.2.3 2019-07-04 06:52:12 -07:00
FreeScout
6e37cdb862 Fix vars js issue 2019-07-04 06:50:27 -07:00
FreeScout
fc82c1a1a0 Update readme 2019-07-04 06:05:57 -07:00
FreeScout
db9103c568 Show detailed error message on updating error 2019-07-04 06:03:41 -07:00
FreeScout
77ab67edcd Show clear cache output in tools.php 2019-07-03 06:12:46 -07:00
FreeScout
f24bd71576 Beautify exception message 2019-07-03 05:49:52 -07:00
FreeScout
5638b3b0ae Hooks in login form 2019-07-03 04:01:15 -07:00
FreeScout
76a1dbd8f1 Custom middleware 2019-07-03 04:00:55 -07:00
FreeScout
71464ab1fe Give names to web routes 2019-07-03 03:59:31 -07:00
FreeScout
6698957104 Fix recipient dropdown when there are other customers in conversation 2019-07-02 22:22:00 -07:00
FreeScout
8eb47b8b69 Detect reply body in Outlook emails 2019-07-02 22:09:29 -07:00
FreeScout
7e9edd5d21 Exclude mailbox emails from recipients on reply 2019-07-02 10:55:11 -07:00
FreeScout
12c11e88d5 Update readme 2019-07-02 09:46:34 -07:00
FreeScout
f653dbb8f9 Fix Eventy Too few arguments error 2019-07-02 06:12:01 -07:00
FreeScout
9e469414b3 Fix displaying To field when forwarding - closes #72 2019-07-02 03:26:42 -07:00
FreeScout
0d3b88c33b Detect reply body in Outlook emails 2019-07-02 02:55:31 -07:00
FreeScout
57ae95616f Merge branch 'master' of github.com:freescout-helpdesk/freescout into dist 2019-07-01 09:30:28 -07:00
FreeScout
b6f5c240e0 Update axios version in package.json 2019-07-01 09:30:07 -07:00
FreeScout
93810fa81a Merge branch 'master' of github.com:freescout-helpdesk/freescout into dist 2019-07-01 09:27:21 -07:00
FreeScout
a4fdf03dbd v1.2.2 2019-07-01 09:26:15 -07:00
FreeScout
4d058110e0 Store vars.js in /storage/js/vars.js 2019-07-01 05:39:31 -07:00
FreeScout
fffedb608b Improve reply detection on fetching 2019-07-01 03:58:44 -07:00
FreeScout
a20b142014 Update default mailbox signature 2019-07-01 03:58:24 -07:00
FreeScout
9f672322e0 Collision detection 2019-07-01 02:12:25 -07:00
FreeScout
1c8c1a0ba9 Merge branch 'master' of github.com:freescout-helpdesk/freescout into dist 2019-06-27 06:12:44 -07:00
FreeScout
bfbdb3681b Update composer.json 2019-06-27 06:11:45 -07:00
FreeScout
b9f3d8736e Merge branch 'master' of github.com:freescout-helpdesk/freescout into dist 2019-06-27 01:57:34 -07:00
FreeScout
290d6d8f54 v1.2.1 2019-06-27 01:56:50 -07:00
FreeScout
0e470df4b6 Fix checking DB connection on installation - closes #279 2019-06-27 01:02:51 -07:00
FreeScout
68588d1bb2 Fix drafts issue - closes #234 2019-06-27 00:17:50 -07:00
FreeScout
3cd7d390c1 Fix Assign to value 2019-06-26 06:21:11 -07:00
FreeScout
a0bf3c4d1b Restart queue:work after changing mailbox sending settings 2019-06-26 05:53:59 -07:00
FreeScout
2cb9e0efbd Update customer email template 2019-06-26 05:26:50 -07:00
FreeScout
5b81cc24e7 Update email delivery services list 2019-06-26 00:23:35 -07:00
FreeScout
b6c53c8795 Fix Data too long for column status_message - closes #259 2019-06-25 10:58:58 -07:00
FreeScout
0aef81100f Show mailbox name in user notification 2019-06-25 00:30:17 -07:00
FreeScout
137e7c0b7b Hide mailbox name in user notification 2019-06-25 00:25:11 -07:00
FreeScout
b87892dc9b Add vendor files to dist 2019-06-24 22:00:06 -07:00
FreeScout
5a640831e2 Merge branch 'master' of github.com:freescout-helpdesk/freescout into dist 2019-06-24 21:57:49 -07:00
FreeScout
c73b11f62c v1.2.0 2019-06-24 21:56:53 -07:00
FreeScout
12cd3c0af7 Forwarding conversations - undoing 2019-06-24 04:51:40 -07:00
FreeScout
51a50a44a4 Restore attachments when editing draft 2019-06-24 02:14:23 -07:00
FreeScout
1e3c024b87 Forwarding conversations - closes #72 2019-06-24 01:15:58 -07:00
FreeScout
1c0c1db43b Forwarding conversations 2019-06-23 22:39:30 -07:00
FreeScout
fac3713af4 Fix Class Helper not found in translation-manager.php 2019-06-21 22:42:00 -07:00
FreeScout
a709f67a00 Fix sending emails to customers with multiple emails - closes #258 2019-06-20 23:36:31 -07:00
FreeScout
790aea27db Update readme 2019-06-20 23:02:23 -07:00
FreeScout
f0af4ea870 Fix URL validation pattern 2019-06-20 22:38:59 -07:00
FreeScout
153ecd726e Prevent saving draft of the message which has been sent 2019-06-20 05:55:58 -07:00
FreeScout
dff86e679c Update readme 2019-06-20 03:43:10 -07:00
FreeScout
2bb93938f9 Edit thread 2019-06-20 03:37:43 -07:00
FreeScout
48e16a54d3 Merge branch 'master' of github.com:freescout-helpdesk/freescout into dist 2019-06-19 23:20:19 -07:00
FreeScout
676652fa09 v1.1.10 2019-06-19 23:19:35 -07:00
FreeScout
294df88809 Take mailbox Validate Certificate settings into account on checking IMAP connection - closes #269 2019-06-19 22:49:06 -07:00
FreeScout
d815de5131 Fix subdirectory paths 2019-06-19 06:00:30 -07:00
FreeScout
32a156c3a6 Fix mailbox email in the sidebar 2019-06-18 23:16:30 -07:00
FreeScout
ed77f937f4 Add bottom margins to settings forms 2019-06-18 02:04:34 -07:00
FreeScout
7070331706 Update readme 2019-06-18 01:57:06 -07:00
FreeScout
3f82986e2c Update readme 2019-06-18 01:48:34 -07:00
FreeScout
7dfbaad817 Fix saving settings in subdirectory installation 2019-06-18 01:43:56 -07:00
FreeScout
4b8a38d7fe Fix fonts and icons paths in CSS 2019-06-17 22:37:32 -07:00
FreeScout
fee5e94239 Add vendor files to dist 2019-06-16 04:17:41 -07:00
FreeScout
57d89b371d Merge branch 'master' of github.com:freescout-helpdesk/freescout into dist 2019-06-16 04:15:47 -07:00
FreeScout
e5ecc679f0 v1.1.9 2019-06-16 04:14:41 -07:00
FreeScout
8e32f5db50 List of email delivery services 2019-06-16 04:05:56 -07:00
FreeScout
edde3c4507 Validate Certificate option for fetching emails - closes #253 #269 2019-06-16 03:27:23 -07:00
FreeScout
ae4e35ef65 Allow installation in a subdirectory 2019-06-16 00:23:17 -07:00
FreeScout
b8633c7711 Allow installation in a subdirectory 2019-06-15 23:47:26 -07:00
FreeScout
cbccc495a9 Allow installation into subdirectory 2019-06-15 08:27:33 -07:00
FreeScout
9d0702800c Allow installation into subdirectory 2019-06-15 07:52:34 -07:00
FreeScout
04b28811a4 Fix Call to a member function url() on null in thread_by.php 2019-06-09 19:33:09 -07:00
FreeScout
bb7c6db8fb Merge branch 'master' of github.com:freescout-helpdesk/freescout into dist 2019-06-05 20:39:46 -07:00
FreeScout
adf3f8f21d v1.1.8 2019-06-05 20:38:47 -07:00
FreeScout
8e0b388fd9 Portugues Brasil translation 2019-06-05 20:33:48 -07:00
FreeScout
d466e62649 Add languages to Readme 2019-06-05 04:15:41 -07:00
FreeScout
307742fb81 Portuguese translation - closes #239 2019-06-05 04:10:37 -07:00
FreeScout
b6c76dd6ed Make folders names translatable - closes #262 2019-06-05 03:17:44 -07:00
FreeScout
e5fb71cf24 Merge pull request #231 from guestisp/fix-195
Fix #195
2019-06-05 15:50:34 +05:45
FreeScout
951765a711 Store Fetch Mail schedule option as app.fetch_schedule 2019-06-05 02:59:39 -07:00
FreeScout
2165cd8be8 Merge pull request #261 from Junker/fetch-schedule-setting
fetch mail schedule setting
2019-06-05 15:23:00 +05:45
FreeScout
c66dcf1bb6 Conversation filter in FetchEmails 2019-06-05 01:16:46 -07:00
FreeScout
30941fc4c0 Do not send notification if conversation is spam 2019-06-04 02:44:20 -07:00
FreeScout
d7d279c7b6 stripTags helper function 2019-06-04 01:13:34 -07:00
FreeScout
6afaa4a809 4th parameter for conversation.status_changed_by_user action 2019-06-04 01:13:06 -07:00
FreeScout
99a0d69269 Private disk for Storage to save files in app/storage 2019-06-04 01:12:16 -07:00
FreeScout
0db95d4f15 Conversation function getFirstThread() 2019-06-03 03:06:42 -07:00
FreeScout
676c431bb2 Do not send notification if conversation is spam 2019-06-02 23:03:17 -07:00
FreeScout
d969b567b3 Remove hardcoded action descriptions 2019-06-02 22:52:37 -07:00
FreeScout
46dfca7865 Added getFolderByType() function to Mailbox 2019-06-02 22:02:58 -07:00
FreeScout
e9c19e26ba Conversation filter in FetchEmails 2019-06-02 22:02:13 -07:00
FreeScout
a2d9b608d1 Not Spam button - stay on the same page 2019-05-10 03:04:58 -07:00
FreeScout
6f64c14ef1 Update readme 2019-05-07 23:14:04 -07:00
FreeScout
4b492d0013 customer_profile.menu hook 2019-05-07 23:11:05 -07:00
FreeScout
02d682c50d Prev status in conversation.status_changed_by_user hook 2019-05-07 22:03:51 -07:00
FreeScout
033283810f Not Spam button 2019-05-07 04:06:47 -07:00
FreeScout
35a02a6816 Redesign - labels 2019-05-06 03:52:22 -07:00
FreeScout
ade6beaffc Static function conversationUrl 2019-05-06 03:30:14 -07:00
FreeScout
e377d5143e customer.profile_data hook 2019-05-06 02:47:45 -07:00
Junker
2ff723f54b fetch-monitor depends on 'fetch_schedule' setting 2019-05-02 22:45:36 +02:00
Junker
504398e5d7 rename setting 'mail_schedule' to 'fetch_schedule'. Add APP_FETCH_SCHEDULE env param. 2019-05-02 22:44:23 +02:00
FreeScout
af57cd0020 Hide Improve Delivery section from mailbox connection settings 2019-05-01 21:46:17 -07:00
FreeScout
399a815526 Show number of conversations in Spam folder 2019-05-01 21:44:38 -07:00
Junker
ff2591550e fetch mail schedule setting 2019-05-01 18:09:03 +02:00
FreeScout
34e3c8d6d9 Merge branch 'master' of github.com:freescout-helpdesk/freescout into dist 2019-04-25 22:05:36 -07:00
FreeScout
8f4d942ced v1.1.7 2019-04-25 22:05:02 -07:00
FreeScout
587623a329 Redesign 2019-04-25 22:03:05 -07:00
FreeScout
bce1220229 Fix redirect to Mine folder after delete conversation in Mine folder 2019-04-25 21:59:45 -07:00
FreeScout
e4c10ccd73 Merge pull request #249 from Junker/fix-delete-conversation-from-mine-folder
fix: redirect back to 'Mine' folder after delete conversation in 'Mine' folder
2019-04-26 10:35:55 +05:45
FreeScout
5e3cba47da Redesign - show mailbox email under title 2019-04-25 21:48:53 -07:00
FreeScout
6bf0210a63 Function to check if user has access to a particular mailbox 2019-04-25 21:27:26 -07:00
FreeScout
ad50d26e0c Helper function to trim non-breaking spaces 2019-04-25 21:26:37 -07:00
FreeScout
941d5171d3 Hooks in user email notifications 2019-04-25 21:26:08 -07:00
FreeScout
8713a9cb97 Update readme 2019-04-25 21:23:59 -07:00
Junker
d434181fd6 fix: redirect to 'mine' folder after delete conversation in 'mine' folder 2019-02-28 07:08:17 +01:00
Alessandro Corbelli
287ca5cbc2 Fix #195 2019-01-10 10:43:36 +01:00
FreeScout
6670ff99cc Merge pull request #230 from guestisp/fix-229 Show error message if user has no permissions to delete conversation
Show error message if user has no permissions to delete conversation
2019-01-10 10:44:04 +03:00
Alessandro Corbelli
cbd71b7dd9 StyleCI 2019-01-09 14:37:09 +01:00
Alessandro Corbelli
ce2c06af06 StyleCI 2019-01-09 14:36:43 +01:00
Alessandro Corbelli
fa62292633 Fix #229 2019-01-09 14:36:02 +01:00
FreeScout
3c6325d7a0 Merge pull request #225 from Junker/conversation-view-action-events new action events for conversation view
new action events for conversation view
2019-01-06 08:10:00 +03:00
Junker
c90e2f9e27 new action events for conversation view 2019-01-05 18:19:19 +01:00
FreeScout
705538582f Merge pull request #223 from Junker/fix-fetch-email-bounce-check fix email bounce check in fetch-emails script
fix email bounce check in fetch-emails script
2019-01-05 07:39:52 +03:00
Junker
2c974afecc fix email bounce check in fetch-emails script 2019-01-04 23:04:31 +01:00
FreeScout
f96a78cb82 Logging on bounce detection 2019-01-04 03:40:34 -08:00
FreeScout
b77e268441 Merge pull request #218 from guestisp/bounce-detection-improvements Bounce detection improvements
Bounce detection improvements
2019-01-04 14:32:03 +03:00
Alessandro Corbelli
b17fccfed0 Removed logs 2019-01-02 12:10:32 +01:00
FreeScout
0ec8a2a942 Merge branch 'master' of github.com:freescout-helpdesk/freescout into dist 2019-01-01 23:01:47 -08:00
FreeScout
24629b8fb4 v1.1.6 2019-01-01 23:00:51 -08:00
FreeScout
9526c6714a Update note_added hook 2018-12-31 01:08:33 -08:00
FreeScout
2471c37fd8 Create thread function 2018-12-31 00:22:43 -08:00
FreeScout
cc78c0e560 Merge branch 'master' of github.com:freescout-helpdesk/freescout into dist 2018-12-28 22:32:17 -08:00
FreeScout
2cb7d81229 v1.1.5 2018-12-28 22:31:34 -08:00
FreeScout
476f120683 Fix switch to note link 2018-12-28 20:58:13 -08:00
FreeScout
72638891fe Redesign 2018-12-28 06:08:23 -08:00
FreeScout
16a7edc0ca Redesign 2018-12-28 05:07:33 -08:00
FreeScout
2fc1b7d3e0 Fix showing attachments in drafts 2018-12-28 04:56:14 -08:00
FreeScout
7069b8e178 Redesign 2018-12-28 04:36:06 -08:00
FreeScout
0cb9961501 Improve background process stucking detection 2018-12-26 23:53:54 -08:00
FreeScout
33dc39d4ad Redesign 2018-12-26 23:04:04 -08:00
FreeScout
5246e77c60 Note should not change conversation status 2018-12-26 23:01:26 -08:00
Alessandro Corbelli
def039f591 More log added 2018-12-22 11:51:07 +01:00
FreeScout
b91e1924e0 Merge branch 'master' of github.com:freescout-helpdesk/freescout into dist 2018-12-21 21:02:22 -08:00
FreeScout
da25e7c359 v1.1.4 2018-12-21 21:01:08 -08:00
Alessandro Corbelli
2a860590d8 Detect bounce from Return-Path 2018-12-21 18:33:33 +01:00
Alessandro Corbelli
0be7557204 Increased log 2018-12-21 18:14:56 +01:00
FreeScout
46b596af8c Merge pull request #212 from freescout-helpdesk/analysis-XWekbe
Apply fixes from StyleCI
2018-12-21 12:11:09 +03:00
FreeScout
90b9254ffb Apply fixes from StyleCI 2018-12-21 09:10:07 +00:00
FreeScout
c74bd56eb3 Set conversation preview when thread is created from draft 2018-12-21 01:09:07 -08:00
FreeScout
d2cdca1f6a Remove script and style tags content from conversation preview 2018-12-21 01:08:47 -08:00
FreeScout
6c584b5c70 Redesign 2018-12-21 00:29:48 -08:00
FreeScout
b9d8540f23 Update pending icon 2018-12-21 00:05:45 -08:00
FreeScout
8adc269058 Merge pull request #188 from guestisp/add-should_save_thread-hook should_save_thread hook
Add "fetch_emails.should_save_thread" hook
2018-12-21 10:49:05 +03:00
FreeScout
416b56aed8 Extend purifier table tags 2018-12-20 23:46:13 -08:00
FreeScout
bd268fd315 Merge pull request #207 from Junker/email-allow-table-tag show table tag in conversation body
show table tags(table,tr,td) in conversation email body
2018-12-21 10:42:08 +03:00
FreeScout
9f391b59fc Remove message/rfc822 contetn type from bounce detection 2018-12-20 23:36:12 -08:00
FreeScout
277b683d98 mailbox.update.after_ticket_status action 2018-12-20 22:28:12 -08:00
FreeScout
150da8a98d Merge pull request #204 from guestisp/add-hook-for-customize-mailbox-update-page Call hook in mailbox update page
Call hook in mailbox update page
2018-12-21 09:19:05 +03:00
FreeScout
4ea0897e3c mailbox.fillable_fields filter 2018-12-20 22:15:41 -08:00
FreeScout
278ecff4ec Merge pull request #203 from guestisp/add-hook-for-customizing-fillable-fields Allow customizing the Mailbox fillable fields by module developers
Allow customizing the Mailbox fillable fields by module developers
2018-12-21 09:07:43 +03:00
Junker
326d37cf1c show table tags(table,tr,td) in conversation email body 2018-12-20 13:29:51 +01:00
Alessandro Corbelli
3c704eec2f Call hook in mailbox update page to allow module developers customize the mailbox update page 2018-12-19 15:40:45 +01:00
Alessandro Corbelli
9b5e4acda0 Allow customizing the Mailbox fillable fields by module developers 2018-12-19 15:36:32 +01:00
Alessandro Corbelli
456cb8491f StyleCI 2018-12-19 14:17:37 +01:00
Alessandro Corbelli
d65ce800af StyleCI 2018-12-19 14:17:03 +01:00
Alessandro Corbelli
a236eb2e11 Replaced $hook object with $data array
Added new hook to allow module developers to change data saved by fetchemails
Replaced fetch_emails.should_save_thread to only use a boolean
2018-12-19 14:15:45 +01:00
Alessandro Corbelli
39c6242f3e Merge branch 'master' into add-should_save_thread-hook 2018-12-19 14:09:22 +01:00
FreeScout
d1e5604e79 Fix deleting conversation having a draft thread 2018-12-18 23:56:56 -08:00
FreeScout
098d3572d6 Fix bulk delete modal layout 2018-12-18 23:34:40 -08:00
FreeScout
d61878a761 Merge pull request #198 from guestisp/fix-197 has_attachments not updated
Fix #197
2018-12-19 10:03:54 +03:00
FreeScout
575b8e43ad Remove tag button from bulk actions panel 2018-12-18 23:00:18 -08:00
FreeScout
22eda49187 Merge pull request #194 from guestisp/fix-191 Select All checkbox doesnt work
Fix #191
2018-12-19 09:57:35 +03:00
FreeScout
0a52c0b542 Merge pull request #193 from guestisp/fix-192 Trying to get property email of non-object
Fix #192
2018-12-19 09:52:59 +03:00
FreeScout
aa1c26a125 Merge pull request #202 from guestisp/fix-201
Manage menu should be removed if no privilges are available
2018-12-19 09:46:27 +03:00
FreeScout
30bbef8285 Automatically recalculate folders counters 2018-12-18 22:38:42 -08:00
FreeScout
74e8e51a43 Merge pull request #200 from guestisp/fix-187
Update folder counters command
2018-12-19 09:26:29 +03:00
Alessandro Corbelli
db64fd2aeb Fix #201 2018-12-18 17:41:29 +01:00
Alessandro Corbelli
fc267329d4 Fix #187 2018-12-18 17:17:07 +01:00
Alessandro Corbelli
fe54b5af4b StyleCI 2018-12-18 17:15:20 +01:00
Alessandro Corbelli
677bca506f Fix #197 2018-12-18 16:21:00 +01:00
Alessandro Corbelli
4371399b41 Fix #191 2018-12-18 12:46:51 +01:00
Alessandro Corbelli
284f0835da Fix #192 2018-12-18 12:40:30 +01:00
Alessandro Corbelli
2b687f3334 StyleCI 2018-12-18 12:35:02 +01:00
Alessandro Corbelli
cf1e89f6ef StyleCI 2018-12-18 12:34:27 +01:00
Alessandro Corbelli
057b814e91 Fix FetchEmails 2018-12-18 12:33:31 +01:00
Alessandro Corbelli
2022bf021e StyleCI 2018-12-17 17:57:41 +01:00
Alessandro Corbelli
7b1cb4d29a StyleCI 2018-12-17 17:50:54 +01:00
Alessandro Corbelli
81e80d30f6 Add "fetch_emails.should_save_thread" hook 2018-12-17 17:45:09 +01:00
FreeScout
77bcdd76c8 On update copy new vendor and rename to avoid error 2018-12-15 21:35:49 -08:00
FreeScout
49cced03c2 Merge branch 'master' of github.com:freescout-helpdesk/freescout into dist 2018-12-15 20:55:50 -08:00
FreeScout
1ed2448c7d v1.1.3 2018-12-15 20:54:57 -08:00
FreeScout
e497c95ff1 Mailbox name in notification to user 2018-12-15 06:00:48 -08:00
FreeScout
5fd1ea35fc Show delivery error message in conversation thread 2018-12-15 05:24:21 -08:00
FreeScout
f54e61dae2 Improve bounce detection 2018-12-15 01:38:53 -08:00
FreeScout
a6fe1ecf87 Redesign 2018-12-15 01:25:44 -08:00
FreeScout
e5bfe957e2 Show delivery error message in conversation thread 2018-12-15 01:15:30 -08:00
FreeScout
36d52d45ef Merge pull request #184 from guestisp/bounce-detection-improvement
Bounce detection improvement
2018-12-15 08:40:05 +03:00
FreeScout
148e89e231 Comments for the process of retrying on send error 2018-12-14 21:28:12 -08:00
FreeScout
19fba8da7a Show release details link 2018-12-14 04:16:09 -08:00
FreeScout
1d69e0052c Check if .env file is writable in System Status 2018-12-14 02:01:03 -08:00
Alessandro Corbelli
0022c3ca15 StyleCI 2018-12-14 10:26:38 +01:00
Alessandro Corbelli
6d3ec46c61 StyleCI 2018-12-14 10:26:04 +01:00
Alessandro Corbelli
211768717e StyleCI 2018-12-14 10:25:21 +01:00
Alessandro Corbelli
8a47b94cdb StyleCI 2018-12-14 10:24:36 +01:00
Alessandro Corbelli
d7a3829a4d More improvements to bounce detection 2018-12-14 10:22:38 +01:00
FreeScout
a125a8d7b7 Do not send auto replies to bounces 2018-12-14 01:10:43 -08:00
Alessandro Corbelli
9b2495edce Small improvement to bounce detection 2018-12-14 09:48:36 +01:00
FreeScout
fd815acf72 Improve bounce detection 2018-12-14 00:18:23 -08:00
FreeScout
6b2071e405 Accept auto responders but do not send auto replies 2018-12-13 22:41:30 -08:00
FreeScout
503bd57d5e Merge pull request #180 from freescout-helpdesk/analysis-8j2yAZ
Apply fixes from StyleCI
2018-12-13 12:11:42 +03:00
FreeScout
d8fbf21579 Apply fixes from StyleCI 2018-12-13 09:11:15 +00:00
FreeScout
9145463243 Editor list 2018-12-13 01:06:20 -08:00
FreeScout
0052b0b62c Show release details link 2018-12-12 23:38:57 -08:00
FreeScout
7f25e75f50 Proper action description name when adding a note 2018-12-12 22:51:02 -08:00
FreeScout
46add87243 Fix last reply by in conversations 2018-12-12 22:40:23 -08:00
FreeScout
78eed5c405 Fix saving settings in env file 2018-12-12 22:00:56 -08:00
FreeScout
574d6bbf8c Merge branch 'master' of github.com:freescout-helpdesk/freescout into dist 2018-12-12 21:14:10 -08:00
FreeScout
021b118916 Replace const with number in user migration 2018-12-12 21:13:49 -08:00
FreeScout
53fc5969db Merge branch 'master' of github.com:freescout-helpdesk/freescout into dist 2018-12-12 20:53:50 -08:00
FreeScout
338c89c53b Redesign 2018-12-12 11:12:41 -08:00
FreeScout
8713e19d78 Merge branch 'master' of github.com:freescout-helpdesk/freescout into dist 2018-12-12 06:39:48 -08:00
FreeScout
9a769154d7 Logs monitoring in Settings - Alerts 2018-12-12 06:39:24 -08:00
FreeScout
ab707bd365 Merge branch 'master' of github.com:freescout-helpdesk/freescout into dist 2018-12-12 06:07:40 -08:00
FreeScout
b6c1daa25e v1.1.2 2018-12-12 06:07:04 -08:00
FreeScout
72c6806fa7 Redesign 2018-12-12 06:06:18 -08:00
FreeScout
d74af3e5c0 Show original message for outgoing thread 2018-12-12 04:31:45 -08:00
FreeScout
adeb8c08f7 Redesign 2018-12-12 04:24:39 -08:00
FreeScout
794bdc2c40 Add target blank to links in threads 2018-12-12 02:36:49 -08:00
FreeScout
3b575c10d1 Redesign 2018-12-12 02:29:09 -08:00
FreeScout
7bba857251 Redesign 2018-12-12 01:41:28 -08:00
FreeScout
b59d8a663c Fix sending draft and reply at the same time 2018-12-12 01:38:25 -08:00
FreeScout
680245e0a9 Redesing 2018-12-12 01:12:40 -08:00
FreeScout
da54367245 Redesign 2018-12-12 00:23:36 -08:00
FreeScout
2b529eb70a Manage mailboxes link in the dashboard 2018-12-11 22:57:13 -08:00
FreeScout
9c19bca5d9 Delete user using flag 2018-12-11 22:43:58 -08:00
FreeScout
2b6ac6a375 Update conversation folder when adding a note 2018-12-11 01:07:34 -08:00
FreeScout
7e4aa4552c Redesign 2018-12-11 00:58:09 -08:00
FreeScout
50a8c8db8a Fix conversation preview updating 2018-12-10 23:41:14 -08:00
FreeScout
84685d1972 Redesign 2018-12-10 23:14:40 -08:00
FreeScout
caf8b26202 Redesign 2018-12-10 22:51:20 -08:00
FreeScout
946132e4b5 Logs monitoring in Settings - Alerts 2018-12-10 04:52:28 -08:00
FreeScout
b9b829db7f Fix getOptions() default value 2018-12-10 00:58:39 -08:00
FreeScout
02bd76ac57 Redesign 2018-12-09 23:28:35 -08:00
FreeScout
9d79f4aea4 Allow to retry and delete failed jobs in System Status 2018-12-09 06:13:00 -08:00
FreeScout
793aaac2e1 Redesign 2018-12-09 02:48:57 -08:00
FreeScout
1d8f79f3a2 Retry failed email jobs 2018-12-09 01:53:36 -08:00
FreeScout
8e978b7b17 Redesign 2018-12-09 01:53:14 -08:00
FreeScout
b5325c9641 QQ reply separator 2018-12-08 23:18:19 -08:00
FreeScout
414ab76cb4 QQ reply separator 2018-12-08 23:15:39 -08:00
FreeScout
ed06f38ddd Redesign 2018-12-08 23:13:18 -08:00
FreeScout
bf7e38a164 Italian translation 2018-12-08 21:21:48 -08:00
FreeScout
c4d58214b6 Redesign 2018-12-08 20:55:00 -08:00
FreeScout
84006b6923 Merge branch 'master' of github.com:freescout-helpdesk/freescout into dist 2018-12-08 05:05:51 -08:00
FreeScout
f69fe6a2e0 v1.1.1 2018-12-08 05:04:43 -08:00
FreeScout
d4e3e73c0d Redesign 2018-12-08 04:53:52 -08:00
FreeScout
35e56b4464 Update conversation preview on reply 2018-12-08 04:15:04 -08:00
FreeScout
6f8c002349 Update conversation preview on reply 2018-12-08 02:14:37 -08:00
FreeScout
40771d962e Fix counters for starred conversations and drafts 2018-12-08 01:00:20 -08:00
FreeScout
2e0567ef87 Redesign 2018-12-08 00:05:30 -08:00
FreeScout
ef24f2fdf8 Fix required password field on user create 2018-12-07 23:42:35 -08:00
FreeScout
456aeb3b8c Redesign 2018-12-07 22:31:55 -08:00
FreeScout
4e0a73623e Redesign 2018-12-07 22:06:42 -08:00
FreeScout
f0498fdd7f Redesign 2018-12-07 21:21:22 -08:00
FreeScout
d79446bf56 Redesign 2018-12-07 06:09:18 -08:00
FreeScout
acb4610b22 Fix in_password commit 2018-12-07 04:58:26 -08:00
FreeScout
d597dee6f7 Merge branch 'master' of github.com:freescout-helpdesk/freescout 2018-12-07 04:55:34 -08:00
FreeScout
7f5c7c3eaf Merge pull request #172 from guestisp/set-in_password-as-nullable
Add nullable to in_password field in mailboxes table
2018-12-07 15:55:12 +03:00
FreeScout
002bac584b Redesign 2018-12-07 04:52:37 -08:00
FreeScout
120131998e Redesign 2018-12-07 02:28:08 -08:00
Alessandro Corbelli
c5cdcdfce2 Removed unneeded migration
Fix nullable in previous migration
2018-12-07 10:55:21 +01:00
FreeScout
c7210de18f Redesign 2018-12-07 01:34:05 -08:00
Alessandro Corbelli
d3ce3e8722 Fix styleci 2018-12-06 12:47:51 +01:00
Alessandro Corbelli
0e79c82013 Fix styleci 2018-12-06 12:47:25 +01:00
Alessandro Corbelli
7c8a25cd4c Add nullable to in_password field in mailboxes table 2018-12-06 11:03:03 +01:00
FreeScout
9b83083bc3 Create conversation from thread 2018-12-06 01:13:04 -08:00
FreeScout
bd063db247 Redesign 2018-12-06 00:05:14 -08:00
FreeScout
65d4e4b8fe Redesign 2018-12-05 23:18:54 -08:00
FreeScout
2373771be8 Show waiting since time in dashboard 2018-12-05 04:33:05 -08:00
FreeScout
4d753b60d3 Fix active assigned conversations count in dashboard 2018-12-05 01:55:37 -08:00
FreeScout
c73ff62369 Merge branch 'master' of github.com:freescout-helpdesk/freescout into dist 2018-12-05 00:26:53 -08:00
FreeScout
570a9cca91 v1.1.0 2018-12-05 00:25:53 -08:00
FreeScout
101ea0ff9a Redesign 2018-12-05 00:08:28 -08:00
FreeScout
40026f4809 Merge branch 'master' of github.com:freescout-helpdesk/freescout 2018-12-04 23:40:27 -08:00
FreeScout
8c44e581f3 Redesign 2018-12-04 23:40:15 -08:00
FreeScout
7eb9caa96c Merge pull request #171 from freescout-helpdesk/analysis-XWkBly
Apply fixes from StyleCI
2018-12-05 10:07:29 +03:00
FreeScout
5c495fd1a5 Apply fixes from StyleCI 2018-12-05 07:06:54 +00:00
FreeScout
471920a0ba User data in signature 2018-12-04 23:05:27 -08:00
FreeScout
1a365ae247 Merge pull request #170 from taoeffect/master
Adds user related variables to signature (Closes #146)
2018-12-05 09:16:49 +03:00
Greg Slepak
16b7e407a0 Adds user related variables to signature (Closes #146) 2018-12-04 19:23:31 -05:00
FreeScout
9bdca967bb Redesign 2018-12-04 06:36:23 -08:00
FreeScout
79bd2f132c Redesign 2018-12-04 05:35:09 -08:00
FreeScout
f42b3c009e Detect and ignore autoresponders 2018-12-04 05:27:10 -08:00
FreeScout
80a765cf0c Check app requried version on module update 2018-12-04 02:43:48 -08:00
FreeScout
c97ec28ecd Redesign 2018-12-04 01:37:24 -08:00
FreeScout
f5ba15269d Update translations in vars.js 2018-12-04 01:09:41 -08:00
FreeScout
51f5149cb6 Fix saving arrays in Settings 2018-12-03 05:48:20 -08:00
FreeScout
e08476b3f8 Merge branch 'master' of github.com:freescout-helpdesk/freescout into dist 2018-12-03 05:06:28 -08:00
FreeScout
bcdf977753 Merge branch 'master' of github.com:freescout-helpdesk/freescout into dist 2018-12-03 05:04:52 -08:00
FreeScout
233dafa67b v1.0.9 2018-12-03 05:03:57 -08:00
FreeScout
8a3af78076 Redesign 2018-12-03 04:52:37 -08:00
FreeScout
f3e616b4a8 Helper functions 2018-12-03 04:52:28 -08:00
FreeScout
33a1374aea Highlight menu item when viewing folder 2018-12-03 02:06:29 -08:00
FreeScout
39cd69c439 Fix UserCreatedConversation event 2018-12-03 02:04:35 -08:00
FreeScout
bbe628e82f Helper functions 2018-12-03 01:03:23 -08:00
FreeScout
a375f96969 Redesign 2018-12-03 01:03:09 -08:00
FreeScout
4682e2df3f Show current date in logs 2018-12-03 00:57:50 -08:00
FreeScout
ba8d7daf53 Show current date in logs 2018-12-02 06:23:10 -08:00
FreeScout
3a4d459872 Redesign 2018-12-02 04:49:02 -08:00
FreeScout
60ee9ff640 Execute background action helper function 2018-12-02 04:47:47 -08:00
FreeScout
b673f1ef4f Redesign - favicon 2018-12-01 21:37:29 -08:00
FreeScout
d8828cab65 Redesign - favicon 2018-12-01 21:30:47 -08:00
FreeScout
52fb8f11a7 Fix Open Mailbox link in dashboard 2018-12-01 21:30:21 -08:00
FreeScout
05f13135a4 Redesign 2018-12-01 01:30:29 -08:00
FreeScout
700fa91850 Add vendor files to dist 2018-12-01 00:36:56 -08:00
FreeScout
6ba2f882e7 Merge branch 'master' of github.com:freescout-helpdesk/freescout into dist 2018-12-01 00:35:46 -08:00
FreeScout
f025df8c8c v1.0.8 2018-12-01 00:34:44 -08:00
FreeScout
79ff47410e French translation 2018-12-01 00:34:23 -08:00
FreeScout
9e0453e90a Improve text 2018-12-01 00:24:31 -08:00
FreeScout
88c317faba Redesign 2018-12-01 00:00:07 -08:00
FreeScout
5e8e37a22e Redesign 2018-11-30 23:30:20 -08:00
FreeScout
cb57f184b0 Redesign 2018-11-30 06:13:19 -08:00
FreeScout
6273c6e79d Redesign 2018-11-30 05:40:26 -08:00
FreeScout
a2a132eecc Hide tooltips on dropdown menu open 2018-11-30 03:29:24 -08:00
FreeScout
5b07fbeb3a Redesign 2018-11-30 03:27:34 -08:00
FreeScout
a57f621dfe Redesign 2018-11-30 01:45:04 -08:00
FreeScout
01d25b1a23 Redesign 2018-11-29 04:56:14 -08:00
FreeScout
1bd75719fe Merge branch 'master' of github.com:freescout-helpdesk/freescout 2018-11-27 22:10:43 -08:00
FreeScout
b37c39b853 Merge pull request #160 from Junker/conversations-mobile-select-longpress
Long press instead of checkboxes in mobile version
2018-11-28 09:10:19 +03:00
FreeScout
9bd0dda3dd Fix options caching 2018-11-27 22:05:13 -08:00
Junker
0885022b15 conversations table: fix attachment icon for mobile version 2018-11-27 10:03:04 +01:00
FreeScout
0c413261b4 Merge branch 'master' of github.com:freescout-helpdesk/freescout 2018-11-27 00:20:47 -08:00
FreeScout
b1f87e64e5 Options default values from config 2018-11-27 00:04:56 -08:00
Junker
0ee49fd9e2 Long press instead of checkboxes in mobile version 2018-11-26 20:55:34 +01:00
FreeScout
32662c4964 Merge pull request #159 from freescout-helpdesk/analysis-qMLB4v
Apply fixes from StyleCI
2018-11-26 15:48:40 +03:00
FreeScout
a59d52339e Apply fixes from StyleCI 2018-11-26 12:47:05 +00:00
FreeScout
447c40483c Fix conversations checkboxes on mobile version 2018-11-26 04:44:29 -08:00
FreeScout
6bc85bf399 Fix typo in FetchMonitor 2018-11-26 04:41:49 -08:00
FreeScout
de7da536bf Merge branch 'master' of github.com:freescout-helpdesk/freescout 2018-11-26 04:39:28 -08:00
FreeScout
d6ead86d46 Langauge option in web installer 2018-11-26 04:38:30 -08:00
FreeScout
0a34644369 Merge branch 'master' into translate 2018-11-26 04:30:22 -08:00
FreeScout
5120af7953 User language 2018-11-26 04:23:27 -08:00
FreeScout
67668a6227 User language 2018-11-26 02:55:37 -08:00
FreeScout
700f140a0e Send user notifications in user language 2018-11-26 02:36:07 -08:00
FreeScout
448db8f273 User language 2018-11-26 02:11:44 -08:00
FreeScout
549a36e7a2 Display custom new languages in Settings 2018-11-26 01:22:05 -08:00
FreeScout
2cf4f914e6 French translation 2018-11-26 01:00:18 -08:00
FreeScout
51d06959ba Importing translations 2018-11-26 00:59:10 -08:00
FreeScout
d4fcaf8a5c Download translations 2018-11-25 23:21:49 -08:00
FreeScout
599e45a479 Merge pull request #158 from dryabov/patch-1
Fix "Class 'App\Console\Commands\Exception' not found" error
2018-11-25 18:17:28 +03:00
FreeScout
a79fb0e74b Translate 2018-11-25 07:11:33 -08:00
FreeScout
286158b177 Importing and exporting translations 2018-11-25 03:18:53 -08:00
FreeScout
cd88e1aa67 Set timezone via Settings 2018-11-24 23:16:20 -08:00
FreeScout
57aec4e132 Check public/modules folder permissions 2018-11-24 08:48:53 -08:00
FreeScout
42eff0f61b Translate 2018-11-24 08:48:06 -08:00
Denis Ryabov
f39dd27fab Fix "Class 'App\Console\Commands\Exception' not found" error 2018-11-24 17:21:40 +03:00
FreeScout
aaabffb9aa Modules cards style 2018-11-24 05:11:20 -08:00
FreeScout
7ae110c866 Permissions and symlinks in System status 2018-11-24 04:08:32 -08:00
FreeScout
332b95965c Add vendor files to dist 2018-11-24 02:27:05 -08:00
FreeScout
463a9e059d Merge branch 'master' of github.com:freescout-helpdesk/freescout into dist 2018-11-24 02:25:57 -08:00
FreeScout
7670ed52ce v1.0.7 2018-11-24 02:25:00 -08:00
FreeScout
dd36c6efb3 Merge pull request #150 from freescout-helpdesk/analysis-zOeVOl
Apply fixes from StyleCI
2018-11-24 13:12:40 +03:00
FreeScout
3e02679738 Apply fixes from StyleCI 2018-11-24 10:11:51 +00:00
FreeScout
bc16a732b4 Fix deleted drafts counter 2018-11-24 02:10:12 -08:00
FreeScout
2d32550714 Merge pull request #149 from Junker/action-threads
add history threads for restore/delete conversation action
2018-11-24 11:57:13 +03:00
FreeScout
de9f0e1be5 Add Fetching finished message to fetch command 2018-11-24 00:52:31 -08:00
Junker
00659e33fb fix thread state on delete conversation 2018-11-24 09:50:10 +01:00
FreeScout
aaba49adf7 Permissions and symlinks in System status 2018-11-24 00:43:28 -08:00
Junker
cad35f5dd7 add history threads for restore/delete conversation action 2018-11-24 09:00:20 +01:00
FreeScout
20cb166ce8 Fix send test email 2018-11-23 23:05:44 -08:00
FreeScout
9f6da13a57 Remove help scout reference from notification settings 2018-11-23 02:59:52 -08:00
FreeScout
d509613d60 Fix typo in mailbox connection settings 2018-11-23 02:56:07 -08:00
FreeScout
cfc7345a9a Check php extensions in modules 2018-11-23 01:06:46 -08:00
FreeScout
5d06587318 Helpder log function 2018-11-23 01:06:32 -08:00
FreeScout
6ae8ba4237 Optimize restore conversation js 2018-11-22 06:55:20 -08:00
FreeScout
1f4c2fef7e Merge pull request #147 from Junker/restore-conversation
Restore conversation
2018-11-22 17:50:58 +03:00
FreeScout
2ccdbc1aa9 Merge branch 'master' of github.com:freescout-helpdesk/freescout 2018-11-22 06:46:06 -08:00
FreeScout
df2fd5bb19 Helper functions 2018-11-22 06:45:50 -08:00
Junker
5ab12c9a23 fix redirect after restore conversation 2018-11-22 08:20:53 +01:00
Junker
d7ea0764e6 restore conversation 2018-11-22 07:43:54 +01:00
FreeScout
d05ef0115d Merge pull request #140 from Junker/fix-conversations-table-checkbox
fix: make conversations checkbox clickable for mobile version
2018-11-20 15:48:57 +03:00
Junker
91726bad33 fix: make conversations checkbox clickable for mobile version 2018-11-20 11:40:29 +01:00
FreeScout
89aac1833d Fallback to utf8 encoding from utf8mb4 for MySQL lower 5.5.3 2018-11-18 03:12:07 -08:00
FreeScout
423f1de5c0 Remove samle db data from env.example 2018-11-18 02:20:51 -08:00
FreeScout
a606ee1861 Hide Enrich Customer Data option 2018-11-18 01:39:07 -08:00
FreeScout
30e45c0558 Fix bool options in settings 2018-11-18 01:20:14 -08:00
FreeScout
70704c2bef Fix processing References header on fetching emails 2018-11-17 23:07:17 -08:00
FreeScout
8e359eda60 Add Yahoo reply separator 2018-11-17 22:45:48 -08:00
FreeScout
fdf1bea596 Note always changes status to Active and never changes Assignee 2018-11-17 22:33:07 -08:00
FreeScout
141635a2a7 Do not show module without aliases 2018-11-17 20:55:20 -08:00
FreeScout
a18c02bdec Improve mailboxes passwords encryption 2018-11-17 20:49:00 -08:00
FreeScout
99e6711b44 Add vendor files to dist 2018-11-17 06:06:07 -08:00
FreeScout
237c2e2c32 Merge branch 'master' of github.com:freescout-helpdesk/freescout into dist 2018-11-17 06:04:21 -08:00
FreeScout
7b0a1bfad4 v1.0.6 2018-11-17 06:01:30 -08:00
FreeScout
2fb503323b Fix he payload is invalid 2018-11-17 05:59:13 -08:00
FreeScout
0d9a332b89 Merge branch 'master' of github.com:freescout-helpdesk/freescout 2018-11-16 23:27:43 -08:00
FreeScout
474f186354 Conversation hooks 2018-11-16 23:21:46 -08:00
FreeScout
1ccc5d2a3f Merge pull request #135 from freescout-helpdesk/analysis-z9GlKN
Apply fixes from StyleCI
2018-11-17 08:04:41 +03:00
FreeScout
28861aec41 Apply fixes from StyleCI 2018-11-17 05:03:57 +00:00
FreeScout
030fc9e97d Fix bulk actions in search 2018-11-16 21:02:49 -08:00
FreeScout
b20e3e3bbb Merge pull request #129 from Junker/conversations-bulk-actions
Conversations bulk actions
2018-11-17 07:58:14 +03:00
FreeScout
0b7657268c Update link in user notification footer 2018-11-16 20:56:50 -08:00
FreeScout
ec2a3d116f Merge branch 'master' of github.com:freescout-helpdesk/freescout into dist 2018-11-16 04:51:07 -08:00
FreeScout
d2f7e5c975 Remove gitter chat from readme 2018-11-16 04:50:27 -08:00
FreeScout
81f319dfea Move Fetch Emails button in Tools 2018-11-16 02:36:13 -08:00
FreeScout
c5de9bece3 Hide Sending Errors in Alerts Settings 2018-11-16 02:32:09 -08:00
FreeScout
c62a87af43 Merge branch 'master' of github.com:freescout-helpdesk/freescout into dist 2018-11-16 02:25:40 -08:00
FreeScout
b53cfe4b57 Do not save latest app version to file 2018-11-16 02:25:09 -08:00
FreeScout
fa902b3dec Merge branch 'master' of github.com:freescout-helpdesk/freescout into dist 2018-11-16 01:41:43 -08:00
FreeScout
e3e7d281ef Add Migrate DB button to Tools 2018-11-16 01:38:00 -08:00
FreeScout
4e993a1ebb Smaller update now button in system status 2018-11-16 01:20:12 -08:00
FreeScout
913a521c77 Disable phpunit testing as dist vendor is cleared by removing unneeded files 2018-11-16 01:15:26 -08:00
FreeScout
fbe7c28b26 Add vendor files to dist 2018-11-16 01:03:16 -08:00
FreeScout
10e9172d9d Merge branch 'master' of github.com:freescout-helpdesk/freescout into dist 2018-11-16 01:01:31 -08:00
FreeScout
8907232133 v.1.0.5 2018-11-16 01:00:53 -08:00
FreeScout
ee3151d085 Updating modules to the latest version 2018-11-16 00:57:37 -08:00
FreeScout
c39c1b4d75 Fix settings general template 2018-11-15 23:24:48 -08:00
FreeScout
46a36fe444 Add vendor files to dist 2018-11-15 23:16:39 -08:00
FreeScout
65eb9bda98 Merge branch 'master' of github.com:freescout-helpdesk/freescout into dist 2018-11-15 23:15:43 -08:00
FreeScout
0c64c7d08c Move mailbox name up in user notification 2018-11-15 22:35:13 -08:00
FreeScout
e5515c20b3 new_conversation_form.after in new conversation 2018-11-15 22:34:36 -08:00
FreeScout
4793a7666d Remove formatting button in editor 2018-11-15 21:40:58 -08:00
FreeScout
3e02ea636c Remove formattings button in editor 2018-11-15 21:19:06 -08:00
FreeScout
0dae0c9146 Update conversation button colors 2018-11-15 05:17:39 -08:00
FreeScout
060d24c95e Use marker in body in addition to Message ID to track replies 2018-11-15 05:03:53 -08:00
FreeScout
556660e6c1 Merge pull request #134 from freescout-helpdesk/analysis-z9GPe6
Apply fixes from StyleCI
2018-11-15 11:38:06 +03:00
FreeScout
c1be80b5d1 Apply fixes from StyleCI 2018-11-15 08:37:26 +00:00
FreeScout
255a8fd3c6 Merge composer.json 2018-11-15 00:32:32 -08:00
FreeScout
a29d832a56 Merge branch 'master' of github.com:freescout-helpdesk/freescout 2018-11-15 00:25:01 -08:00
Junker
c6cabafb20 moved conversation bulk actions code to ajax function 2018-11-15 08:13:14 +01:00
FreeScout
d2219b1673 Fix customer name in search 2018-11-14 22:35:41 -08:00
FreeScout
62d4a553d3 Styles and hooks 2018-11-14 22:35:25 -08:00
Junker
ff938c2239 Conversations bulk actions 2018-11-14 20:06:59 +01:00
FreeScout
2599e8293b Merge pull request #124 from guestisp/encrypt-mailbox-passwords
Crypt password used for email fetching
2018-11-14 12:17:11 +03:00
Alessandro Corbelli
6d8c5eeae0 Using doctrine/dbal for migrations 2018-11-14 09:49:18 +01:00
FreeScout
1c086a6c68 Enable debugbar provider autodiscovery 2018-11-14 00:01:27 -08:00
FreeScout
3e8e6f7095 Show link to logs in System status in case of fetch errors 2018-11-13 22:32:02 -08:00
FreeScout
a22e4538ab Override Laravel ProviderRepository.php to catch provider not found errors on updating 2018-11-13 22:27:07 -08:00
FreeScout
b323086c09 Add vendor files to dist 2018-11-13 22:08:27 -08:00
FreeScout
b09d957b12 Merge branch 'master' of github.com:freescout-helpdesk/freescout into dist 2018-11-13 22:06:15 -08:00
FreeScout
30ab811ba2 Merge branch 'master' of github.com:freescout-helpdesk/freescout 2018-11-13 22:03:47 -08:00
FreeScout
6aca1bea71 Override Laravel ProviderRepository.php to catch provider not found errors on updating 2018-11-13 22:03:34 -08:00
FreeScout
3287172473 Override Laravel ProviderRepository.php to catch provider not found errors on updating 2018-11-13 21:44:36 -08:00
FreeScout
d8acd413f4 Debugbar is enabled only if APP_ENV=local 2018-11-13 10:56:57 -08:00
FreeScout
06cdae9a87 Merge branch 'master' of github.com:freescout-helpdesk/freescout into dist 2018-11-13 09:32:29 -08:00
FreeScout
0e5e88d8ff Merge pull request #126 from guestisp/fix-125
Fix #125
2018-11-13 19:50:41 +03:00
Alessandro Corbelli
390fad48fb Fix #125 2018-11-13 15:45:29 +01:00
Alessandro Corbelli
5dec3b4e2d More styleci fixes 2018-11-13 15:06:56 +01:00
Alessandro Corbelli
340b277204 apply styleci fixes 2018-11-13 15:06:16 +01:00
Alessandro Corbelli
66930b7408 Crypt password used for email fetching 2018-11-13 15:04:26 +01:00
FreeScout
cfc59939f7 Email Template option hidden until somebody needs it 2018-11-13 05:53:28 -08:00
FreeScout
f2dedc0dfe Merge pull request #119 from guestisp/fix-spread_the_Word
Fix typo
2018-11-13 16:21:01 +03:00
FreeScout
5708909360 Settings hooks 2018-11-13 05:17:53 -08:00
Alessandro Corbelli
3f6a5fd2aa Fix typo 2018-11-13 12:44:44 +01:00
FreeScout
aa994eb2a5 Add PostgreSQL support 2018-11-12 23:15:48 -08:00
FreeScout
41bef2e90e Fix customers table index length 2018-11-12 22:46:38 -08:00
FreeScout
d1ba487fcd Check if .env.example exists in web installer 2018-11-12 22:45:05 -08:00
FreeScout
adab9fc7a8 Merge branch 'master' of github.com:freescout-helpdesk/freescout into dist 2018-11-12 06:04:51 -08:00
FreeScout
52942138f3 Enable open tracking by default 2018-11-12 06:04:07 -08:00
FreeScout
f16ec8422a Do not show last commit in update script 2018-11-12 05:49:17 -08:00
FreeScout
5b94ae8aa4 Add vendor files to dist 2018-11-12 05:42:30 -08:00
FreeScout
116c826262 Merge branch 'master' of github.com:freescout-helpdesk/freescout into dist 2018-11-12 05:40:12 -08:00
FreeScout
bf8460fc91 Merge branch 'master' of github.com:freescout-helpdesk/freescout 2018-11-12 05:38:32 -08:00
FreeScout
63156fb3b4 v1.0.4 2018-11-12 05:37:16 -08:00
FreeScout
d99636afb5 Merge pull request #116 from freescout-helpdesk/analysis-zGngEk
Apply fixes from StyleCI
2018-11-12 16:35:47 +03:00
FreeScout
c7745d424e Apply fixes from StyleCI 2018-11-12 13:35:06 +00:00
FreeScout
91bad70bdf Open tracking tuning 2018-11-12 05:23:19 -08:00
FreeScout
536a80d1c1 Merge pull request #105 from guestisp/email-open-tracking
Add tracking of opened emails
2018-11-12 15:53:02 +03:00
FreeScout
79957c1e58 Modules 2018-11-12 04:40:23 -08:00
Alessandro Corbelli
fae04cb1eb Fix Thread 2018-11-12 11:24:02 +01:00
Alessandro Corbelli
2a3df36798 Merge from master 2018-11-12 11:22:50 +01:00
Alessandro Corbelli
2ada8c787b Use tooltip for showing the full date of opening
Also fix #108
2018-11-12 11:18:48 +01:00
Alessandro Corbelli
80e1e47d1b Improvements on email open tracking 2018-11-12 11:09:36 +01:00
FreeScout
21412e8047 Merge pull request #114 from freescout-helpdesk/analysis-8bK04l
Apply fixes from StyleCI
2018-11-12 12:32:52 +03:00
FreeScout
6346437754 Apply fixes from StyleCI 2018-11-12 09:12:57 +00:00
FreeScout
a2e35bacbd Check passed parameters in \MailHelper::replaceMailVars() 2018-11-11 22:59:14 -08:00
FreeScout
074f98f375 Check php version in index.php and artisan 2018-11-11 21:50:43 -08:00
FreeScout
321987beb4 Styles updated 2018-11-11 21:26:40 -08:00
FreeScout
9a36e88451 New hooks 2018-11-11 21:26:26 -08:00
FreeScout
cd421c7afc Cache modules in memory 2018-11-11 21:25:45 -08:00
FreeScout
f1214bcaba Check PHP version in update script 2018-11-11 08:46:27 -08:00
FreeScout
f1b460be65 Add hint to Next Conversation field 2018-11-10 02:50:28 -08:00
FreeScout
93bc42bbc0 When creating conversation show number instead of ID 2018-11-10 02:45:35 -08:00
FreeScout
913f7d12f4 Merge pull request #102 from guestisp/add-next-ticket-feature
Allow to set the next conversation number
2018-11-10 13:43:21 +03:00
FreeScout
2db883812e Use version_compare in version check 2018-11-10 02:22:54 -08:00
Alessandro Corbelli
9a1bcac262 Add tracking of opened emails 2018-11-09 15:09:42 +01:00
Alessandro Corbelli
51a25ab804 - Option::remove('next_ticket') only if next_ticket is set
- Next Conversation # should display current value from the option or current max(number)+1
- Fix "if" by following Laravel standards
2018-11-09 11:35:38 +01:00
Alessandro Corbelli
80ae8f117f Allow to set the next conversation number 2018-11-09 10:28:08 +01:00
5745 changed files with 207156 additions and 487303 deletions

12
.editorconfig Normal file
View File

@@ -0,0 +1,12 @@
root = true
[*]
charset = utf-8
end_of_line = lf
indent_style = space
indent_size = 4
insert_final_newline = true
trim_trailing_whitespace = true
[*.json]
insert_final_newline = false

View File

@@ -9,23 +9,39 @@
# Application URL
APP_URL=https://example.com
# Use HTTP protocol and redirect to HTTPS
#APP_FORCE_HTTPS=true
# If you are using HTTPS, feel free to uncomment this line to improve security
#SESSION_SECURE_COOKIE=true
# Enter your proxy address here if freescout.net is not available from your server
# (access to freescout.net is required to obtain official modules)
#APP_PROXY=
# Custom headers to add to all outgoing emails.
#APP_CUSTOM_MAIL_HEADERS="IsTransactional:True;X-Custom-Header:value"
# Uncomment if you have many folders and you are experiencing performance issues
#APP_UPDATE_FOLDER_COUNTERS_IN_BACKGROUND=true
# Timezones: https://github.com/freescout-helpdesk/freescout/wiki/PHP-Timezones
# Comment it to use default timezone from php.ini
#APP_TIMEZONE=Europe/London
# Comma separated list of trusted proxies for proper IP detection in FreeScout.
# To trust all proxies that connect to your server use single asterisk: *
# To trust ALL proxies, including those that are in a chain of forwarding use double asterisk: **
#APP_TRUSTED_PROXIES=192.168.1.1,192.168.1.2,192.168.1.3
DB_CONNECTION=mysql
DB_HOST=localhost
DB_PORT=3306
DB_DATABASE=freescout
DB_USERNAME=freescout
DB_PASSWORD=XXX
DB_DATABASE=
DB_USERNAME=
# Maximum password length is 50 characters
DB_PASSWORD=
# Run the following console command to generate the key: php artisan key:generate
# Otherwise application will show the following error: "Whoops, looks like something went wrong"
APP_KEY=
# Uncomment to see errors in your browser, don't forget to comment it back when debugging finished
#APP_DEBUG=true
#APP_DEBUG=true

View File

@@ -0,0 +1,25 @@
---
name: General Help Request
about: Create a general help request
---
<!--
* If you have some error the first thing you should do is to check "Manage » Logs » App Logs"! If there are any errors there - make sure to provide them in the issue.
* Have you read FAQ? https://github.com/freescout-helpdesk/freescout/wiki/FAQ
* If you have "Whoops something went wrong" error see: https://github.com/freescout-helpdesk/freescout/wiki/Installation-Guide#11-troubleshooting
* Before creating an issue try to disable all non-official modules and remove all custom code from your FreeScout and see if the issue still persists.
* Feature requests for modules should be posted here: https://freescout.net/request-feature/
* Docker questions should go here: https://github.com/tiredofit/docker-freescout/issues
* Create separate issues for different topics - no need to mix all your problems into one issue.
* Questions on issues with payments for modules should be sent by email: https://freescout.net/contact-us/
* Don't forget that you are not the project manager. Try to be humble, polite, friendly and positive. Otherwise your account may be banned (and it can't be undone).
* Mentioning how much you've spent on modules is also the way to be banned.
Still here? Well clean this out and go ahead :)
-->
PHP version:
FreeScout version:
Database: MySQL / PostgreSQL
Are you using CloudFlare: Yes / No
Are you using non-official modules: Yes / No

3
.github/PULL_REQUEST_TEMPLATE.md vendored Normal file
View File

@@ -0,0 +1,3 @@
Keep in mind that pull requests should be sent to the `master` branch! See https://github.com/freescout-helpdesk/freescout/wiki/Development-Guide#github-workflow
Now you can delete this text and type the description of your pull request...

20
.github/workflows/lint-php.yml vendored Normal file
View File

@@ -0,0 +1,20 @@
name: PHP Code Sniffer
on:
workflow_dispatch:
jobs:
build:
name: Lint PHP
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v3
- name: Setup PHP
uses: shivammathur/setup-php@v2
with:
php-version: 8.3
tools: phpcs
- name: Run check
run: phpcs

59
.github/workflows/test-pgsql.yml vendored Normal file
View File

@@ -0,0 +1,59 @@
name: Test App (PostgreSQL)
on:
push:
branches:
- master
workflow_dispatch:
jobs:
test:
name: Test App (PostgreSQL)
runs-on: ubuntu-latest
env:
DB_CONNECTION: testing_pgsql
services:
postgres:
image: postgres:latest
env:
POSTGRES_USER: freescout-test
POSTGRES_PASSWORD: freescout-test
POSTGRES_DB: freescout-test
ports:
- 5432:5432
# Set health checks to wait until postgres has started
options: >-
--health-cmd pg_isready
--health-interval 10s
--health-timeout 5s
--health-retries 5
strategy:
matrix:
php: ['7.3', '7.4', '8.0', '8.1', '8.2']
steps:
- uses: actions/checkout@v3
- name: Setup PHP
uses: shivammathur/setup-php@v2
with:
php-version: ${{ matrix.php }}
extensions: pgsql, mbstring, xml, imap, zip, gd, curl, intl, json
- name: Install composer dependencies
run: composer install --ignore-platform-reqs --no-interaction
- name: Migrate and seed the database
run: |
php${{ matrix.php }} artisan migrate --force -n --database=testing_pgsql
php${{ matrix.php }} artisan db:seed --force -n --database=testing_pgsql
env:
DB_PORT: ${{ job.services.postgres.ports[5432] }}
- name: Run PHP tests
run: php${{ matrix.php }} ./vendor/bin/phpunit
env:
DB_PORT: ${{ job.services.postgres.ports[5432] }}

45
.github/workflows/test.yml vendored Normal file
View File

@@ -0,0 +1,45 @@
name: Test App (MySQL)
on:
push:
branches:
- master
workflow_dispatch:
jobs:
test:
name: Test App (MySQL)
runs-on: ubuntu-latest
strategy:
matrix:
php: ['7.3', '7.4', '8.0', '8.1', '8.2']
steps:
- uses: actions/checkout@v3
- name: Setup PHP
uses: shivammathur/setup-php@v2
with:
php-version: ${{ matrix.php }}
extensions: mysql, mbstring, xml, imap, zip, gd, curl, intl, json
- name: Start MySQL
run: |
sudo systemctl start mysql
- name: Setup database
run: |
mysql -uroot -proot -e 'CREATE DATABASE IF NOT EXISTS `freescout-test`;'
mysql -uroot -proot -e "CREATE USER 'freescout-test'@'localhost' IDENTIFIED WITH mysql_native_password BY 'freescout-test';"
mysql -uroot -proot -e "GRANT ALL ON \`freescout-test\`.* TO 'freescout-test'@'localhost';"
mysql -uroot -proot -e 'FLUSH PRIVILEGES;'
- name: Install composer dependencies
run: composer install --ignore-platform-reqs --no-interaction
- name: Migrate and seed the database
run: |
php${{ matrix.php }} artisan migrate --force -n --database=testing
php${{ matrix.php }} artisan db:seed --force -n --database=testing
- name: Run PHP tests
run: php${{ matrix.php }} ./vendor/bin/phpunit

8
.gitignore vendored
View File

@@ -14,7 +14,7 @@ Homestead.yaml
npm-debug.log
yarn-error.log
.env
app/Console/Commands/Test*
/bootstrap/compiled.php
composer.phar
#composer.lock
@@ -27,6 +27,10 @@ Thumbs.db
/Modules
/Modules/**/.git
/public/modules
/public/docs
/storage/.ignore_locales
/storage/.installed
/tools
/tools
.well-known
/resources/lang/module.*
.phpunit.result.cache

View File

@@ -1,4 +1,10 @@
# On some hostings it is impossible to change web root directory
# so we rewrite all web requests into /public folder
RewriteEngine on
RewriteRule (.*) /public/$1 [L]
<IfModule mod_rewrite.c>
RewriteEngine on
# On some hostings it does not work as "public/$1", but works as "/public/$1".
# But we can't write it as "/public/$1" because in this case it does not work
# when application is installed in subdirectory.
RewriteCond %{REQUEST_URI} !/\.well\-known/?.*
RewriteRule (.*) public/$1 [L]
</IfModule>

View File

@@ -3,10 +3,13 @@ language: php
php:
- 7.0
- 7.2
- 7.4
- 8.0
before_script:
- cp .env.travis .env
- mysql -e 'create database homestead_test;'
script:
- vendor/bin/phpunit
# phpunit testing is disabled as dist vendor is cleared by removing unneeded files
#script:
# - vendor/bin/phpunit

View File

@@ -522,7 +522,7 @@ contain the covered work, unless you entered into that arrangement,
or that patent license was granted, prior to 28 March 2007.
Nothing in this License shall be construed as excluding or limiting
any implied license or other defenses to infringement that may
any implied license or other defences to infringement that may
otherwise be available to you under applicable patent law.
12. No Surrender of Others' Freedom.

100
README.md
View File

@@ -2,73 +2,123 @@
<div align="center">
<img src="https://raw.githubusercontent.com/freescout-helpdesk/freescout/master/public/img/logo-300.png" width="180" height="180" />
<img src="https://raw.githubusercontent.com/freescout-help-desk/freescout/master/public/img/logo-300.png" width="180" height="180" />
<br/><br/>
[![PHP version](https://freescout-helpdesk.github.io/img/badges/PHP-7.0%2B-blue.svg)](https://github.com/freescout-helpdesk/freescout#requirements) [![Laravel version](https://freescout-helpdesk.github.io/img/badges/Laravel-5.5-blue.svg)](https://github.com/freescout-helpdesk/freescout#requirements)
[![Build Status](https://travis-ci.org/freescout-helpdesk/freescout.svg?branch=dist)](https://freescout-helpdesk.github.io/img/badges/travis.svg) [![Join the chat at https://gitter.im/freescout-helpdesk/Lobby](https://badges.gitter.im/freescout-helpdesk/Lobby.svg)](https://gitter.im/freescout-helpdesk/Lobby?utm_source=badge&utm_medium=badge&utm_campaign=pr-badge&utm_content=badge) [![HitCount](http://hits.dwyl.io/freescout-helpdesk/freescout.svg)](http://hits.dwyl.io/freescout-helpdesk/freescout)
[![PHP version](https://freescout-helpdesk.github.io/img/badges/PHP-7.1%2B-blue.svg)](https://github.com/freescout-help-desk/freescout#requirements) [![Hits](https://hits.seeyoufarm.com/api/count/incr/badge.svg?url=https%3A%2F%2Fgithub.com%2Ffreescout-helpdesk%2Ffreescout&count_bg=%2379C83D&title_bg=%23555555&icon=&icon_color=%23E7E7E7&title=hits&edge_flat=false)](https://hits.seeyoufarm.com)
</div>
**FreeScout** is the super lightweight free open source help desk and shared inbox written in PHP7 (Laravel 5.5 framework) – self hosted clone of HelpScout. Now you can enjoy [free Zendesk & Help Scout](https://freescout.net) without giving up privacy or locking yourself into a service you don't control.
**FreeScout** is the super lightweight and powerful free open source help desk and shared inbox built with PHP (Laravel framework). Now you can enjoy free Zendesk & Help Scout without giving up privacy or locking yourself into a service you don't control. FreeScout has been developed from scratch and is not using any copyrighted Help Scout or Zendesk materials.
FreeScout has been developed from scratch and is not using any copyrighted Help Scout materials to comply with GitHub's [DMCA Policy](https://help.github.com/articles/dmca-takedown-policy/) (trademark, logos, icons, CSS, JS, HTML files are copyrighted; idea, look and feel cannot be copyrighted).
If you want to support the project feel free to **star this repository**. It helps to increase the visibility of the project and let people know that it is valuable. Thanks for your support!
![FreeScout](https://freescout-helpdesk.github.io/img/screenshots/screenshot.png)
## Table of Contents
* [Demo](#demo)
* [Features](#features)
* [Mobile Apps](#mobile-apps)
* [Requirements](#requirements)
* [News & Updates](#news--updates)
* [Installation](#installation)
* [Cloud Hosted](#cloud-hosted)
* [Modules](#modules)
* [Tools & Integrations](#tools--integrations)
* [News & Updates](#news--updates)
* [Contributing](#contributing)
* [Screenshots](#screenshots)
## Demo
**[Live Demo](https://demo.freescout.net)**
## Features
![FreeScout](https://raw.githubusercontent.com/freescout-helpdesk/freescout/master/public/img/banner.png)
* No limitations on the number of users, tickets, mailboxes, etc.
* 100% Mobile-friendly.
* Multilingual.
* Multilingual: English, Chinese, Croatian, Czech, Danish, Dutch, Finnish, French, German, Italian, Japanese, Kazakh, 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.
* Merging conversations.
* Moving conversations between mailboxes.
* Phone conversations.
* Sending new conversations to multiple recipients at once.
* Collision detection – notice is shown when two agents open the same conversation.
* Push notifications.
* Following a conversation.
* Auto reply.
* Notes.
* Internal notes.
* Automatic refreshing of the conversations list without the need to reload the page.
* Pasting screenshots from the clipboard into the reply area.
* Dragging images into the reply area.
* Configuring notifications on a per user basis.
* Open tracking.
* Editing threads.
* Search.
* Edit/hide threads.
* And more…
Need anything else? Suggest features [here](https://feedback.userreport.com/25a3cb5f-e4bd-4470-b6f3-79fcfaa8e90f/#ideas/popular)
Need anything else? Suggest features [here](https://freescout.net/request-feature/).
## Mobile Apps
Mobile apps support the same functionality and modules as the web version of your FreeScout installation. Both support agents and administrators can use mobile apps.
<a href="https://freescout.net/android-app/" target="_blank" rel="nofollow"><img alt="Android App" src="https://freescout-helpdesk.github.io/img/apps/android.png" width="200px" /></a> <a href="https://freescout.net/ios-app/" target="_blank" rel="nofollow"><img alt="iOS App" src="https://freescout-helpdesk.github.io/img/apps/ios.png?v=1" width="200px" /></a>
## Requirements
FreeScout is a pure PHP/MySQL application, so it can be easily deployed even on a shared hosting.
FreeScout is a pure PHP/MySQL application, so it can be easily deployed even on a [shared hosting](https://2ly.link/20rhd).
* Nginx / Apache / IIS
* PHP 7.0+
* MySQL/MariaDB 5.0+
* PHP 7.1 - 8.x
* MySQL 5.0+ / MariaDB 5.0+ / PostgreSQL
## News & Updates
If you would like to be notified about new releases, news and updates you can subscribe [here](https://feedburner.google.com/fb/a/mailverify?uri=freescout)
There are no minimum system requirements (CPU / RAM) – FreeScout will run on any system.
## Installation
[Installation Guide](https://github.com/freescout-helpdesk/freescout/wiki/Installation-Guide)
[Installation Guide](https://github.com/freescout-help-desk/freescout/wiki/Installation-Guide)
Images & one-click installs:
* [Docker Image](http://freescout.net/docker/)
* [Softaculous](http://www.softaculous.com/apps/customersupport/FreeScout) (cPanel, Plesk, ISPmanager, H-Sphere, DirectAdmin, InterWorx)
* [Fantastico](http://ff3.netenberg.com/visitors/scripts/freescout/view) (cPanel, DirectAdmin, ISP Manager, ISP Config)
* [Cloudron](https://cloudron.io/store/net.freescout.cloudronapp.html)
* [Ubuntu](https://github.com/freescout-help-desk/freescout/wiki/Installation-Guide#interactive-installation-bash-script-ubuntu) (bash script)
## Cloud Hosted
[Cloud Hosted FreeScout](https://freescout.net/cloud-hosted/)
## Modules
FreeScout [Modules](https://github.com/freescout-helpdesk/freescout/wiki/FreeScout-Modules)
* [Official Modules](https://freescout.net/modules/)
* [Community Modules](https://freescout.net/community-modules/)
## Tools & Integrations
* [API](https://api-docs.freescout.net/)
* [Migrate to FreeScout](http://freescout.net/migrate/) (from any help desk)
* [Zapier](https://freescout.net/zapier/)
* [Make](https://freescout.net/make-integration/) (Integromat)
## News & Updates
Don't miss news, updates and new modules!
[Email Newsletter](https://freescout.net/subscribe/) | [Facebook](https://freescout.net/facebook/) | [Twitter](https://freescout.net/twitter/) | [YouTube](https://freescout.net/youtube/) | [Telegram](https://freescout.net/telegram/) | [RSS](https://freescout.net/feed/)
## Contributing
* [Development Guide](https://github.com/freescout-helpdesk/freescout/wiki/Development-Guide)
* [Todo list](https://github.com/freescout-helpdesk/freescout/projects/1)
* [Translate](https://github.com/freescout-helpdesk/freescout/wiki/Translate)
* [Support project by leaving a feedback](https://github.com/freescout-helpdesk/freescout/wiki#support-project)
* [Support the project by leaving a feedback](https://github.com/freescout-help-desk/freescout/issues/288)
* [Development Guide](https://github.com/freescout-help-desk/freescout/wiki/Development-Guide)
* [Todo list](https://github.com/freescout-help-desk/freescout/labels/help%20wanted)
* [Translate](https://github.com/freescout-help-desk/freescout/wiki/Translate)
## Screenshots

5
SECURITY.md Normal file
View File

@@ -0,0 +1,5 @@
# Security Policy
## Reporting a Vulnerability
Email at support@freescout.net

View File

@@ -13,6 +13,15 @@ class ActivityLog extends Activity
const NAME_SYSTEM = 'system';
const NAME_APP_LOGS = 'app';
public static $available_logs = [
self::NAME_USER,
self::NAME_OUT_EMAILS,
self::NAME_EMAILS_SENDING,
self::NAME_EMAILS_FETCHING,
self::NAME_SYSTEM,
self::NAME_APP_LOGS,
];
const DESCRIPTION_USER_LOGIN = 'login';
const DESCRIPTION_USER_LOGOUT = 'logout';
const DESCRIPTION_USER_REGISTER = 'register';
@@ -55,7 +64,7 @@ class ActivityLog extends Activity
case self::DESCRIPTION_EMAILS_SENDING_ERROR_ALERT:
return __('Error sending alert');
case self::DESCRIPTION_EMAILS_SENDING_WRONG_EMAIL:
return __('Error sending email to the user who replied to notiication from wrong email');
return __('Error sending email to the user who replied to notification from wrong email');
case self::DESCRIPTION_EMAILS_FETCHING_ERROR:
return __('Error fetching email');
case self::DESCRIPTION_SYSTEM_ERROR:
@@ -87,7 +96,7 @@ class ActivityLog extends Activity
case self::NAME_APP_LOGS:
return __('App Logs');
default:
return ucfirst($log_name);
return ucwords(str_replace('_', ' ', $log_name));
}
}
@@ -95,6 +104,32 @@ class ActivityLog extends Activity
{
$col = str_replace('_', ' ', $col);
$col = ucfirst($col);
return $col;
}
/**
* Get log names.
*
* @return [type] [description]
*/
public static function getLogNames()
{
return self::select('log_name')->distinct()->pluck('log_name')->toArray();
}
/**
* Get available log names.
*
* @return [type] [description]
*/
public static function getAvailableLogs($check_existing = true)
{
$available_logs = self::$available_logs;
if ($check_existing) {
$available_logs = array_merge($available_logs, self::getLogNames());
}
return array_unique(\Eventy::filter('activity_log.available_logs', self::$available_logs));
}
}

View File

@@ -19,6 +19,10 @@ class Attachment extends Model
const DIRECTORY = 'attachment';
CONST DISK = 'private';
CONST MIME_TYPE_MAX_LENGTH = 127;
// https://github.com/Webklex/laravel-imap/blob/master/src/IMAP/Attachment.php
public static $types = [
'message' => self::TYPE_MESSAGE,
@@ -32,13 +36,8 @@ class Attachment extends Model
'other' => self::TYPE_OTHER,
];
/**
* Files with such extensions are being renamed on upload.
*/
public static $restricted_extensions = [
'php.*',
'sh',
'pl',
public static $type_extensions = [
self::TYPE_VIDEO => ['flv', 'mp4', 'm3u8', 'ts', '3gp', 'mov', 'avi', 'wmv']
];
public $timestamps = false;
@@ -60,30 +59,84 @@ class Attachment extends Model
return false;
}
// Check extension.
$extension = strtolower(pathinfo($file_name, PATHINFO_EXTENSION));
if (preg_match('/('.implode('|', self::$restricted_extensions).')/', $extension)) {
// Add underscore to the extension if file has restricted extension.
$file_name = $file_name.'_';
// Sanitize mime type.
// https://github.com/freescout-helpdesk/freescout/issues/3048
$mime_duplicate = strpos($mime_type, "application/vnd.openxmlformats", 1);
if ($mime_duplicate) {
$mime_type = substr($mime_type, $mime_duplicate);
}
$mime_type = substr($mime_type, 0, self::MIME_TYPE_MAX_LENGTH);
$orig_extension = pathinfo($file_name, PATHINFO_EXTENSION);
// Add underscore to the extension if file has restricted extension.
$file_name = \Helper::sanitizeUploadedFileName($file_name, $uploaded_file, $content);
// Replace some symbols in file name.
// Gmail can not load image if it contains spaces.
$file_name = str_replace(' ', '-', $file_name);
$file_name = preg_replace('/[ #\/]/', '_', $file_name);
// Replace soft hyphens.
$file_name = str_replace(html_entity_decode('&#xAD;'), '_', $file_name);
if (!$file_name) {
if (!$orig_extension) {
preg_match("/.*\/([^\/]+)$/", $mime_type, $m);
if (!empty($m[1])) {
$orig_extension = $m[1];
}
}
$file_name = uniqid();
if ($orig_extension) {
$file_name .= '.'.$orig_extension;
}
}
// https://github.com/freescout-helpdesk/freescout/issues/2385
// Fix for webklex/php-imap.
if ($file_name == 'undefined' && $mime_type == 'message/rfc822') {
$file_name = 'RFC822.eml';
}
// https://github.com/freescout-helpdesk/freescout/issues/1412#issuecomment-1658881493
if ($file_name == 'undefined' && $mime_type == 'text/calendar') {
$file_name = 'calendar.ics';
}
if (strlen($file_name) > 255) {
$without_ext = pathinfo($file_name, PATHINFO_FILENAME);
$extension = pathinfo($file_name, PATHINFO_EXTENSION);
// 125 because file name may have unicode symbols.
$file_name = \Helper::substrUnicode($without_ext, 0, 125-strlen($extension)-1);
$file_name .= '.'.$extension;
}
if (!$type) {
$type = self::detectType($mime_type);
$type = self::detectType($mime_type, $orig_extension);
}
$attachment = new self();
$attachment->thread_id = $thread_id;
$attachment->user_id = $user_id;
$attachment->user_id = $user_id;
$attachment->file_name = $file_name;
$attachment->mime_type = $mime_type;
$attachment->type = $type;
$attachment->embedded = $embedded;
$attachment->type = $type;
$attachment->embedded = $embedded;
$attachment->save();
$file_info = self::saveFileToDisk($attachment, $file_name, $content, $uploaded_file);
$attachment->file_dir = $file_info['file_dir'];
$attachment->size = Storage::disk(self::DISK)->size($file_info['file_path']);
$attachment->save();
return $attachment;
}
/**
* Save file to the disk and return file_dir.
*/
public static function saveFileToDisk($attachment, $file_name, $content, $uploaded_file)
{
// Save file from content or copy file.
// We have to keep file name as is, so if file exists we create extra folder.
// Examples: 1/2/3
@@ -93,26 +146,31 @@ class Attachment extends Model
do {
$i++;
$file_path = self::DIRECTORY.DIRECTORY_SEPARATOR.$file_dir.$i.DIRECTORY_SEPARATOR.$file_name;
} while (Storage::exists($file_path));
} while (Storage::disk(self::DISK)->exists($file_path));
$file_dir .= $i.DIRECTORY_SEPARATOR;
if ($uploaded_file) {
$uploaded_file->storeAs(self::DIRECTORY.DIRECTORY_SEPARATOR.$file_dir, $file_name);
} else {
Storage::put($file_path, $content);
try {
if ($uploaded_file) {
$uploaded_file->storeAs(self::DIRECTORY.DIRECTORY_SEPARATOR.$file_dir, $file_name, ['disk' => self::DISK]);
} else {
Storage::disk(self::DISK)->put($file_path, $content);
}
} catch (\Exception $e) {
\Helper::logException($e, '[Attachment::saveFileToDisk()]');
}
$attachment->file_dir = $file_dir;
$attachment->size = Storage::size($file_path);
$attachment->save();
\Helper::sanitizeUploadedFileData($file_path, \Helper::getPrivateStorage(), $content);
return $attachment;
return [
'file_dir' => $file_dir,
'file_path' => $file_path,
];
}
/**
* Get file path.
* Examples: 1/2, 1/3
* Examples: 1/2, 1/3.
*
* @param int $id
*
@@ -144,17 +202,23 @@ class Attachment extends Model
/**
* Detect attachment type by it's mime type.
*
* @param string $mime_type
*
* @param string $mime_type
*
* @return int
*/
public static function detectType($mime_type)
public static function detectType($mime_type, $extension = '')
{
if (preg_match("/^text\//", $mime_type)) {
return self::TYPE_TEXT;
} elseif (preg_match("/^message\//", $mime_type)) {
return self::TYPE_MESSAGE;
} elseif (preg_match("/^application\//", $mime_type)) {
// This is tricky mime type.
// For .mp4 mime type can be application/octet-stream
if (!empty($extension) && in_array(strtolower($extension), self::$type_extensions[self::TYPE_VIDEO])) {
return self::TYPE_VIDEO;
}
return self::TYPE_APPLICATION;
} elseif (preg_match("/^audio\//", $mime_type)) {
return self::TYPE_AUDIO;
@@ -170,7 +234,7 @@ class Attachment extends Model
}
/**
* Conver type name to integer.
* Convert type name to integer.
*/
public static function typeNameToInt($type_name)
{
@@ -188,7 +252,51 @@ class Attachment extends Model
*/
public function url()
{
return Storage::url($this->getStorageFilePath());
$file_path = $this->getStorageFilePath();
// URL must contain only forward slashes.
$file_path = str_replace(DIRECTORY_SEPARATOR, '/', $file_path);
$file_url = Storage::url($file_path);
// Fix percents.
// https://github.com/freescout-helpdesk/freescout/issues/3530
$file_url = str_replace('%', '%25', $file_url);
return $file_url.'?id='.$this->id.'&token='.$this->getToken();
}
/**
* Get hashed security token for the attachment.
*/
public function getToken()
{
// \Hash::make() may contain . and / symbols which may cause problems.
return md5(config('app.key').$this->id.$this->size);
}
/**
* Outputs the current Attachment as download
*/
public function download($view = false)
{
$headers = [];
// #533
//return $this->getDisk()->download($this->getStorageFilePath(), \Str::ascii($this->file_name));
if ($view) {
$headers['Content-Disposition'] = '';
}
$file_name = $this->file_name;
if ($file_name == "RFC822"){
$file_name = $file_name.'.eml';
}
return $this->getDisk()->download($this->getStorageFilePath(), $file_name, $headers);
}
private function getDisk() {
return Storage::disk(self::DISK);
}
/**
@@ -201,14 +309,32 @@ class Attachment extends Model
return self::formatBytes($this->size);
}
/**
* attachment/...
*/
public function getStorageFilePath()
{
return self::DIRECTORY.DIRECTORY_SEPARATOR.$this->file_dir.$this->file_name;
}
public function getLocalFilePath()
/**
* /var/html/storage/app/attachment/...
*/
public function getLocalFilePath($full = true)
{
return Storage::path(self::DIRECTORY.DIRECTORY_SEPARATOR.$this->file_dir.$this->file_name);
if ($full) {
return $this->getDisk()->path(self::DIRECTORY.DIRECTORY_SEPARATOR.$this->file_dir.$this->file_name);
} else {
return DIRECTORY_SEPARATOR.'storage'.DIRECTORY_SEPARATOR.'app'.DIRECTORY_SEPARATOR.self::DIRECTORY.DIRECTORY_SEPARATOR.$this->file_dir.$this->file_name;
}
}
/**
* Check if the attachment file actually exists on the disk.
*/
public function fileExists()
{
return $this->getDisk()->exists(self::DIRECTORY.DIRECTORY_SEPARATOR.$this->file_dir.$this->file_name);
}
public static function formatBytes($size, $precision = 0)
@@ -227,23 +353,106 @@ class Attachment extends Model
/**
* Delete attachments from disk and DB.
* Embeds are not taken into account.
*
* @param array $attachments
*
* @param array $attachments
*/
public static function deleteByIds($attachment_ids)
{
if (!count($attachment_ids)) {
return;
}
$attachments = Attachment::whereIn('id', $attachment_ids)->get();
$attachments = self::whereIn('id', $attachment_ids)->get();
// Delete from disk
self::deleteForever($attachments);
}
/**
* Delete attachments by thread IDs.
*/
public static function deleteByThreadIds($thread_ids)
{
if (!count($thread_ids)) {
return;
}
$attachments = self::whereIn('thread_id', $thread_ids)->get();
// Delete from disk
self::deleteForever($attachments);
}
public static function deleteForever($attachments)
{
// Delete from disk
foreach ($attachments as $attachment) {
echo $attachment->getStorageFilePath().' ';
Storage::delete($attachment->getStorageFilePath());
$attachment->getDisk()->delete($attachment->getStorageFilePath());
}
// Delete from DB
Attachment::whereIn('id', $attachment_ids)->delete();
self::whereIn('id', $attachments->pluck('id')->toArray())->delete();
}
/**
* Delete attachments and update Thread & Conversation.
*/
public static function deleteAttachments($attachments)
{
if (!$attachments instanceof \Illuminate\Support\Collection) {
$attachments = collect($attachments);
}
foreach ($attachments as $attachment) {
if ($attachment->thread_id && $attachment->thread
&& count($attachment->thread->attachments) <= 1
) {
$attachment->thread->has_attachments = false;
$attachment->thread->save();
// Update conversation.
$conversation = $attachment->thread->conversation;
foreach ($conversation->threads as $thread) {
if ($thread->has_attachments) {
break 2;
}
}
$conversation->has_attachments = false;
$conversation->save();
}
}
Attachment::deleteForever($attachments);
}
/**
* Create a copy of the attachment and it's file.
*/
public function duplicate($thread_id = null)
{
$new_attachment = $this->replicate();
$new_attachment->thread_id = $thread_id;
$new_attachment->save();
try {
$attachment_file = new \Illuminate\Http\UploadedFile(
$this->getLocalFilePath(), $this->file_name,
null, null, true
);
$file_info = Attachment::saveFileToDisk($new_attachment, $new_attachment->file_name, '', $attachment_file);
if (!empty($file_info['file_dir'])) {
$new_attachment->file_dir = $file_info['file_dir'];
$new_attachment->save();
}
} catch (\Exception $e) {
\Helper::logException($e);
}
return $new_attachment;
}
public function getFileContents()
{
return $this->getDisk()->get($this->getStorageFilePath());
}
}

View File

@@ -3,16 +3,13 @@
* Created by PhpStorm.
* User: leemason
* Date: 31/10/15
* Time: 00:20
* Time: 00:20.
*/
namespace App\Broadcasting\Broadcasters;
use Carbon\Carbon;
use Illuminate\Broadcasting\Broadcasters\Broadcaster;
use Illuminate\Foundation\Application;
use Illuminate\Database\DatabaseManager;
use Illuminate\Support\Str;
use Symfony\Component\HttpKernel\Exception\AccessDeniedHttpException;
@@ -43,21 +40,22 @@ class PolycastBroadcaster extends Broadcaster
// insert the new event
\DB::table('polycast_events')->insert([
'channels' => json_encode($channels),
'event' => $event,
'payload' => json_encode($payload),
'created_at' => Carbon::now()->toDateTimeString()
'channels' => json_encode($channels),
'event' => $event,
'payload' => json_encode($payload),
'created_at' => Carbon::now()->toDateTimeString(),
]);
}
/**
* Authenticate the incoming request for a given channel.
*
* @param \Illuminate\Http\Request $request
* @param \Illuminate\Http\Request $request
*
* @return mixed
*/
public function auth($request) {
public function auth($request)
{
// For connect request
if (empty($request->channels)) {
return true;
@@ -67,19 +65,20 @@ class PolycastBroadcaster extends Broadcaster
foreach ($request->channels as $channel_name => $channel_info) {
// Copied from Illuminate\Broadcasting\Broadcasters\PusherBroadcaster
if (Str::startsWith($channel_name, ['private-', 'presence-']) &&
! $request->user()) {
echo 1;
exit();
throw new AccessDeniedHttpException;
!$request->user()) {
throw new AccessDeniedHttpException();
}
$channelName = Str::startsWith($channel_name, 'private-')
? Str::replaceFirst('private-', '', $channel_name)
: Str::replaceFirst('presence-', '', $channel_name);
// This throws an exception
parent::verifyUserCanAccessChannel(
$request, $channelName
);
if (Str::startsWith($channel_name, ['private-', 'presence-'])) {
$channelName = Str::startsWith($channel_name, 'private-')
? Str::replaceFirst('private-', '', $channel_name)
: Str::replaceFirst('presence-', '', $channel_name);
// This throws an exception if needed.
parent::verifyUserCanAccessChannel(
$request, $channelName
);
}
}
return true;
@@ -88,11 +87,13 @@ class PolycastBroadcaster extends Broadcaster
/**
* Return the valid authentication response.
*
* @param \Illuminate\Http\Request $request
* @param mixed $result
* @param \Illuminate\Http\Request $request
* @param mixed $result
*
* @return mixed
*/
public function validAuthenticationResponse($request, $result) {
public function validAuthenticationResponse($request, $result)
{
// By some reason this is never called
return false;
@@ -107,20 +108,20 @@ class PolycastBroadcaster extends Broadcaster
// ]]);
}
public function isDeferred()
{
public function isDeferred()
{
return false;
}
}
/**
* Created as there was an error:
* "Call to undefined method App\Broadcasting\Broadcasters\PolycastBroadcaster::channel()"
*
* It is called from routes/channels.php
*/
/*
* Created as there was an error:
* "Call to undefined method App\Broadcasting\Broadcasters\PolycastBroadcaster::channel()"
*
* It is called from routes/channels.php
*/
// public function channel($channel, callable $callback)
// {
// return true;
// //return (int) $user->id === (int) $id;
// }
}
}

View File

@@ -3,19 +3,17 @@
namespace App\Channels;
use App\Events\RealtimeBroadcastNotificationCreated;
use RuntimeException;
use Illuminate\Notifications\Notification;
use Illuminate\Contracts\Events\Dispatcher;
use Illuminate\Notifications\Channels\BroadcastChannel;
use Illuminate\Notifications\Messages\BroadcastMessage;
use Illuminate\Notifications\Notification;
class RealtimeBroadcastChannel extends BroadcastChannel
{
/**
* Send the given notification immediately using non-quable event.
*
* @param mixed $notifiable
* @param \Illuminate\Notifications\Notification $notification
* @param mixed $notifiable
* @param \Illuminate\Notifications\Notification $notification
*
* @return array|null
*/
public function send($notifiable, Notification $notification)

View File

@@ -0,0 +1,117 @@
<?php
namespace App\Console\Commands;
use Carbon\Carbon;
use Illuminate\Console\Command;
class CheckConvViewers extends Command
{
/**
* The name and signature of the console command.
*
* @var string
*/
protected $signature = 'freescout:check-conv-viewers';
/**
* The console command description.
*
* @var string
*/
protected $description = 'Check if user finished viewing conversation';
/**
* Create a new command instance.
*
* @return void
*/
public function __construct()
{
parent::__construct();
}
/**
* Execute the console command.
*
* @return mixed
*/
public function handle()
{
// Check dates in cache.
$cache_key = 'conv_view';
$cache_data = \Cache::get($cache_key);
if (empty($cache_data) || !is_array($cache_data)) {
return;
}
$now = Carbon::now();
$need_update = false;
foreach ($cache_data as $conversation_id => $conv_data) {
if (empty($conv_data) || !is_array($conv_data)) {
continue;
}
foreach ($conv_data as $user_id => $data) {
if (!isset($data['t']) || !isset($data['r'])) {
continue;
}
$view_date = Carbon::createFromFormat('Y-m-d H:i:s', $data['t']);
if ($view_date && $now->diffInSeconds($view_date) > 25) {
// Remove user from viewers.
unset($cache_data[$conversation_id][$user_id]);
if (empty($cache_data[$conversation_id])) {
unset($cache_data[$conversation_id]);
}
$need_update = true;
\Cache::forget('conv_view_'.$user_id.'_'.$conversation_id);
// Create event to let other users know that user finished viewing conversation.
$notification_data = [
'conversation_id' => $conversation_id,
'user_id' => $user_id,
];
event(new \App\Events\RealtimeConvViewFinish($notification_data));
\Eventy::action('conversation.view.finish', $conversation_id, $user_id, $now->diffInSeconds($view_date));
}
}
}
if ($need_update) {
// Update conversation cache data.
\Cache::put($cache_key, $cache_data, 20 /*minutes*/);
}
/*$cache_key = 'conv_view_'.$this->user_id.'_'.$this->conversation_id;
$cache_data = \Cache::get($cache_key);
if (!isset($cache_data['t']) || !isset($cache_data['r'])) {
return;
}
$view_date = Carbon::createFromFormat('Y-m-d H:i:s', $cache_data['t']);
$now = Carbon::now();
if ($view_date && $now->diffInSeconds($view_date) > 30) {
$cache_key = 'conv_view';
if (!empty($cache_data[$this->conversation_id]) && !empty($cache_data[$this->conversation_id][$this->user_id])) {
// Remove user from viewers.
unset($cache_data[$this->conversation_id][$this->user_id]);
// Update conversation cache data.
\Cache::put($cache_key, $cache_data, 1);
}
// Create event to let other users know that user finished viewing conversation.
$notification_data = [
'conversation_id' => $conversation->id,
'user_id' => $user->id,
];
event(new \App\Events\RealtimeConvViewFinish($notification_data));
}*/
}
}

View File

@@ -0,0 +1,63 @@
<?php
namespace App\Console\Commands;
use Illuminate\Console\Command;
class CheckRequirements extends Command
{
/**
* The name and signature of the console command.
*
* @var string
*/
protected $signature = 'freescout:check-requirements';
/**
* The console command description.
*
* @var string
*/
protected $description = 'Check console version of PHP';
/**
* Create a new command instance.
*
* @return void
*/
public function __construct()
{
parent::__construct();
}
/**
* Execute the console command.
*
* @return mixed
*/
public function handle()
{
// PHP extensions.
$php_extensions = \Helper::checkRequiredExtensions();
$this->comment("PHP Version");
$this->line(' '.str_pad(phpversion(), 30, '.'). ' '.(version_compare(phpversion(), config('installer.core.minPhpVersion'), '>=') ? '<fg=green>OK</>' : '<fg=red>NOT FOUND</>'), false);
$this->comment("PHP Extensions");
$this->output($php_extensions);
// Functions.
$functions = \Helper::checkRequiredFunctions();
$this->comment("Functions");
$this->output($functions);
$this->line('');
}
public function output($items)
{
foreach ($items as $item => $status) {
$this->line(' '.str_pad($item, 30, '.'). ' '.($status ? '<fg=green>OK</>' : '<fg=red>NOT FOUND</>'), false);
}
}
}

View File

@@ -0,0 +1,48 @@
<?php
namespace App\Console\Commands;
use Illuminate\Console\Command;
class CleanNotificationsTable extends Command
{
const PERIOD = '-6 months';
/**
* The name and signature of the console command.
*
* @var string
*/
protected $signature = 'freescout:clean-notifications-table';
/**
* The console command description.
*
* @var string
*/
protected $description = 'Delete old read records from notifications table.';
/**
* Create a new command instance.
*
* @return void
*/
public function __construct()
{
parent::__construct();
}
/**
* Execute the console command.
*
* @return mixed
*/
public function handle()
{
\DB::table('notifications')->where('created_at', '<', \Carbon\Carbon::now()->modify(self::PERIOD))
->whereNotNull('read_at')
->delete();
$this->info('['.date('Y-m-d H:i:s').'] Deleted old read notifications for: '.self::PERIOD);
}
}

View File

@@ -0,0 +1,46 @@
<?php
namespace App\Console\Commands;
use Illuminate\Console\Command;
class CleanSendLog extends Command
{
const PERIOD = '-6 months';
/**
* The name and signature of the console command.
*
* @var string
*/
protected $signature = 'freescout:clean-send-log';
/**
* The console command description.
*
* @var string
*/
protected $description = 'Delete old records from send log.';
/**
* Create a new command instance.
*
* @return void
*/
public function __construct()
{
parent::__construct();
}
/**
* Execute the console command.
*
* @return mixed
*/
public function handle()
{
$logs = \App\SendLog::where('created_at', '<', \Carbon\Carbon::now()->modify(self::PERIOD))->delete();
$this->info('['.date('Y-m-d H:i:s').'] Deleted send logs: '.self::PERIOD);
}
}

View File

@@ -0,0 +1,46 @@
<?php
namespace App\Console\Commands;
use Illuminate\Console\Command;
// When processing attachments FreeScout may create files in /tmp folder.
// So it's good to clean this folder periodically.
class CleanTmp extends Command
{
/**
* The name and signature of the console command.
*
* @var string
*/
protected $signature = 'freescout:clean-tmp';
/**
* The console command description.
*
* @var string
*/
protected $description = 'Remove from system temp folder FreeScout files older than 1 week to avoid "No space left on device"';
/**
* Create a new command instance.
*
* @return void
*/
public function __construct()
{
parent::__construct();
}
/**
* Execute the console command.
*
* @return mixed
*/
public function handle()
{
\Helper::shellExec('find '.\Helper::getTempDir().' -mtime +7 -type f -name '.\Helper::getTempFilePrefix().'* -exec rm -r -f {} \;');
$this->comment("Done");
}
}

View File

@@ -11,7 +11,7 @@ class ClearCache extends Command
*
* @var string
*/
protected $signature = 'freescout:clear-cache {--doNotCacheConfig}';
protected $signature = 'freescout:clear-cache {--doNotCacheConfig} {--doNotGenerateVars}';
/**
* The console command description.
@@ -44,6 +44,19 @@ class ClearCache extends Command
$this->call('config:clear');
} else {
$this->call('config:cache');
// Laravel users `require` function to include config.php
// If opcache is being used for few seconds config.php is being cached.
if (function_exists('opcache_invalidate')) {
opcache_invalidate(app()->getCachedConfigPath());
}
}
// Regenerate vars to get new data from .env
if (!$this->option('doNotGenerateVars')) {
$this->call('freescout:generate-vars');
}
// This should not be done during installation.
if (\Helper::isInstalled()) {
\Helper::queueWorkerRestart();
}
}
}

View File

@@ -12,7 +12,7 @@ class CreateUser extends Command
*
* @var string
*/
protected $signature = 'freescout:create-user';
protected $signature = 'freescout:create-user {--role=} {--firstName=} {--lastName=} {--email=} {--password=}';
/**
* The console command description.
@@ -46,40 +46,57 @@ class CreateUser extends Command
).'.model'
);
$user = new $class();
$fillables = ['role', 'first_name', 'last_name', 'email', 'password'];
foreach ($fillables as $key => $fillable) {
if ($fillable == 'password') {
$user->$fillable = \Hash::make($this->secret(($key + 1).'/'.count($fillables)." User $fillable"));
} elseif ($fillable == 'role') {
$user->$fillable = $this->ask(($key + 1).'/'.count($fillables)." User $fillable (admin/user)", 'admin');
if (!$user->$fillable) {
$user->$fillable = 'admin';
}
while (!in_array($user->$fillable, User::$roles)) {
$this->error('Incorrect role');
$user->$fillable = $this->ask('Please enter valid role');
}
$user->$fillable = array_flip(User::$roles)[$user->$fillable];
} else {
$user->$fillable = $this->ask(($key + 1).'/'.count($fillables)." User $fillable");
if ($fillable == 'email') {
while (!filter_var($user->$fillable, FILTER_VALIDATE_EMAIL)) {
$this->error('Incorrect email address');
$user->$fillable = $this->ask('Please enter valid email address');
}
}
$user->role = $this->option('role');
if ($user->role ) {
if (!in_array($user->role , User::$roles)) {
$this->error('Invalid role');
return false;
}
} else {
$user->role = $this->ask('User role (admin/user)', 'admin');
while (!in_array($user->role, User::$roles)) {
$this->error('Invalid role');
$user->role = $this->ask('Please enter valid role');
}
}
$user->role = array_flip(User::$roles)[$user->role];
$user->first_name = $this->option('firstName') ? $this->option('firstName') : $this->ask('User first name');
$user->last_name = $this->option('lastName') ? $this->option('lastName') : $this->ask('User last name');
$user->email = $this->option('email');
if ($user->email) {
if (!filter_var($user->email, FILTER_VALIDATE_EMAIL)) {
$this->error('Invalid email address');
return false;
}
} else {
$user->email = $this->ask('User email address');
while (!filter_var($user->email, FILTER_VALIDATE_EMAIL)) {
$this->error('Incorrect email address');
$user->email = $this->ask('Please enter valid email address');
}
}
$user->password = \Hash::make($this->option('password') ? $this->option('password') : $this->secret('User password'));
if ($this->confirm('Do you want to create the user?', true)) {
if ($user->isAdmin()) {
$user->invite_state = User::INVITE_STATE_ACTIVATED;
}
$user->save();
$this->info("User created (id: {$user->id})");
try {
$user->save();
} catch (\Exception $e) {
$this->line($e->getMessage());
$this->error('User already exists.');
return false;
}
}
$this->info('User created with id: '.$user->id);
return true;
}
}

File diff suppressed because it is too large Load Diff

View File

@@ -39,12 +39,16 @@ class FetchMonitor extends Command
{
$now = time();
$last_successful_run = \Option::get('fetch_emails_last_successful_run');
if ($last_successful_run && $last_successful_run < $now - \Option::get('alert_fetch_period')*60) {
$options = \Option::getOptions([
'alert_fetch_period',
'fetch_emails_last_successful_run',
]);
$last_successful_run = $options['fetch_emails_last_successful_run'];
if ($last_successful_run && $last_successful_run < $now - ((config('app.fetch_schedule') * 60) + ($options['alert_fetch_period'] * 60))) {
$mins_ago = floor(($now - $last_successful_run) / 60);
$text = 'There are some problems fetching emails: last time emails were successfully fetched <strong>'.$mins_ago.' minutes ago</strong>. Please check <a href="'.route('logs', ['name' => 'fetch_errors']).'">fetching logs</a> and <a href="'.route('system').'#cron">make sure</a> that the flollowing cron task is running: <code>php artisan schedule:run</code>';
$text = 'There are some problems fetching emails: last time emails were successfully fetched <strong>'.$mins_ago.' minutes ago</strong>. Please check <a href="'.route('logs', ['name' => 'fetch_errors']).'">fetching logs</a> and <a href="'.route('system').'#cron">make sure</a> that the following cron task is running: <code>php artisan schedule:run</code>';
if (\Option::get('alert_fetch') && !\Option::get('alert_fetch_sent')) {
// We send alert only once

View File

@@ -43,18 +43,33 @@ class GenerateVars extends Command
{
try {
$params = [
'locales' => config('app.locales'),
'locales' => \Helper::getAllLocales(),
];
$filesystem = new Filesystem();
//$filesystem = new Filesystem();
$file_path = public_path('js/vars.js');
//$file_path = public_path('js/vars.js');
$file_path = storage_path('app/public/js/vars.js');
$compiled = view('js/vars', $params)->render();
$content = view('js/vars', $params)->render();
$filesystem->put($file_path, $compiled);
$this->info("Created: {$file_path}");
//$filesystem->put($file_path, $content);
// Save vars only if content changed
try {
if (\Storage::exists('js/vars.js')) {
$old_content = \Storage::get('js/vars.js');
if ($content != $old_content) {
\Storage::put('js/vars.js', $content);
}
} else {
\Storage::put('js/vars.js', $content);
}
$this->info("Created: ".substr($file_path, strlen(base_path())+1));
} catch (\Exception $e) {
$msg = "Error occurred saving /storage/app/public/js/vars.js. ".\Helper::formatException($e);
\Log::error($msg);
$this->error($msg);
}
} catch (\Exception $e) {
$this->error($e->getMessage());
}

View File

@@ -0,0 +1,61 @@
<?php
namespace App\Console\Commands;
use Illuminate\Console\Command;
class LogoutUsers extends Command
{
/**
* The name and signature of the console command.
*
* @var string
*/
protected $signature = 'freescout:logout-users';
/**
* The console command description.
*
* @var string
*/
protected $description = 'Logout all users';
/**
* Create a new command instance.
*
* @return void
*/
public function __construct()
{
parent::__construct();
}
/**
* Execute the console command.
*
* @return mixed
*/
public function handle()
{
try {
// Remove files from storage/frameworks/sessions
$files = \File::files(storage_path('framework/sessions'));
$count = 0;
foreach ($files as $file) {
try {
$deleted = \File::delete($file->getPathname());
if ($deleted) {
$count++;
}
} catch (\Exception $e) {
$this->error($e->getMessage());
}
}
$this->line('Deleted sessions: '.$count);
} catch (\Exception $e) {
$this->error($e->getMessage());
}
}
}

View File

@@ -0,0 +1,96 @@
<?php
namespace App\Console\Commands;
use Illuminate\Console\Command;
class LogsMonitor extends Command
{
/**
* The name and signature of the console command.
*
* @var string
*/
protected $signature = 'freescout:logs-monitor';
/**
* The console command description.
*
* @var string
*/
protected $description = 'Send new log records by email';
/**
* Create a new command instance.
*
* @return void
*/
public function __construct()
{
parent::__construct();
}
/**
* Execute the console command.
*
* @return mixed
*/
public function handle()
{
$now = \Carbon\Carbon::now();
$options = \Option::getOptions([
'alert_logs_names',
'alert_logs_period',
], [
'alert_logs_period' => config('app.alert_logs_period'),
]);
if (!$options['alert_logs_names']) {
$this->error('['.date('Y-m-d H:i:s').'] No logs to monitor selected');
return;
}
if (!$options['alert_logs_period']) {
$this->error('['.date('Y-m-d H:i:s').'] No logs monitoring period set');
return;
}
$logs = \App\ActivityLog::whereIn('log_name', $options['alert_logs_names'])
->where('created_at', '>=', \Carbon\Carbon::now()->modify('-1 '.$options['alert_logs_period'])->toDateTimeString())
->where('created_at', '<', $now->toDateTimeString())
->get();
if (!count($logs)) {
$this->line('['.date('Y-m-d H:i:s').'] No new log records found for the last '.$options['alert_logs_period']);
return;
}
$names = $logs->pluck('log_name')->unique()->toArray();
$text = 'Logs having new records for the last '.$options['alert_logs_period'].':<ul>';
foreach ($names as $name) {
$text .= '<li>';
$text .= '<strong>'.\App\ActivityLog::getLogTitle($name).'</strong>';
$text .= '</li>';
}
$text .= '</ul>';
foreach ($names as $name) {
$text .= '<br/><strong>'.\App\ActivityLog::getLogTitle($name).'</strong><br/>';
foreach ($logs as $log) {
if ($log->log_name != $name) {
continue;
}
$text .= '● ['.$log->created_at.'] '.$log->getEventDescription().' <code>'.$log->properties.'</code><br/>';
}
}
// Send alert.
\MailHelper::sendAlertMail($text, 'Logs Monitoring');
$this->line($text);
$this->info('['.date('Y-m-d H:i:s').'] Monitoring finished');
}
}

View File

@@ -52,6 +52,7 @@ class ModuleBuild extends Command
}
if (!$modules_aliases) {
$this->error('No modules found');
return;
}
$all = true;
@@ -70,6 +71,7 @@ class ModuleBuild extends Command
$module = \Module::findByAlias($module_alias);
if (!$module) {
$this->error('Module with the specified alias not found: '.$module_alias);
return;
}
$this->buildModule($module);
@@ -84,6 +86,7 @@ class ModuleBuild extends Command
$public_symlink = public_path('modules').DIRECTORY_SEPARATOR.$module->alias;
if (!file_exists($public_symlink)) {
$this->error('Public symlink ['.$public_symlink.'] not found. Run module installation command first: php artisan freescout:module-install');
return;
}
@@ -108,7 +111,6 @@ class ModuleBuild extends Command
}
$this->info("Created: {$file_path}");
} catch (\Exception $e) {
$this->error($e->getMessage());
}

View File

@@ -0,0 +1,102 @@
<?php
namespace App\Console\Commands;
use App\Misc\WpApi;
use Illuminate\Console\Command;
class ModuleCheckLicenses extends Command
{
/**
* The name and signature of the console command.
*
* @var string
*/
protected $signature = 'freescout:module-check-licenses';
/**
* The console command description.
*
* @var string
*/
protected $description = 'Check licenses for modules';
/**
* Create a new command instance.
*
* @return void
*/
public function __construct()
{
parent::__construct();
}
/**
* Execute the console command.
*
* @return mixed
*/
public function handle()
{
// Get active official modules and check validity of their licenses
$modules = \Module::getActive();
$this->info('Active modules found: '.count($modules));
$params = [
'url' => \App\Module::getAppUrl(),
'data' => [],
];
foreach ($modules as $module) {
$license = $module->getLicense();
if (!$module->isOfficial() || !$license) {
continue;
}
$data['license'] = $license;
$data['module_alias'] = $module->getAlias();
$params['data'][] = $data;
}
$result = WpApi::checkLicenses($params);
if (!empty($result['statuses'])) {
foreach ($modules as $module) {
$module_alias = $module->getAlias();
foreach ($result['statuses'] as $result_module_alias => $status) {
if ($result_module_alias != $module_alias) {
continue;
}
if (!empty($status) && $status != 'valid') {
$msg = 'Module '.$module->getName().' has been deactivated due to invalid license: '.$status;
$this->error($module->getName().': '.$msg);
// Deactive module
\App\Module::deactiveModule($module->getAlias(), true);
// Inform admin
\Log::error($msg);
activity()
->withProperties([
'error' => $msg,
])
->useLog(\App\ActivityLog::NAME_SYSTEM)
->log(\App\ActivityLog::DESCRIPTION_SYSTEM_ERROR);
} else {
$this->info($module->getName().': OK');
}
continue 2;
}
$this->info($module->getName().': Unknown status');
}
}
$this->info('Checking licenses finished');
}
}

View File

@@ -1,7 +1,8 @@
<?php
/**
* php artisan freescout:module-install modulealias
* php artisan freescout:module-install modulealias.
*/
namespace App\Console\Commands;
use Illuminate\Console\Command;
@@ -20,7 +21,7 @@ class ModuleInstall extends Command
*
* @var string
*/
protected $description = 'Install module or all modules (if module_alias is empty)';
protected $description = 'Install module or all modules (if module_alias is empty): run migrations and create a symlink';
/**
* Create a new command instance.
@@ -56,6 +57,7 @@ class ModuleInstall extends Command
}
if (!$modules_aliases) {
$this->error('No modules found');
return;
}
$install_all = $this->confirm('You have not specified a module alias, would you like to install all available modules ('.implode(', ', $modules_aliases).')?');
@@ -74,6 +76,7 @@ class ModuleInstall extends Command
$module = \Module::findByAlias($module_alias);
if (!$module) {
$this->error('Module with the specified alias not found: '.$module_alias);
return;
}
$this->call('module:migrate', ['module' => $module->getName(), '--force' => true]);
@@ -83,19 +86,53 @@ class ModuleInstall extends Command
$this->call('freescout:clear-cache');
}
// There is similar function in \App\Module.
public function createModulePublicSymlink($module)
{
$from = public_path('modules').DIRECTORY_SEPARATOR.$module->alias;
$to = $module->getExtraPath('Public');
if (file_exists($from)) {
return $this->info('Public symlink already exists');
}
// file_exists() may throw "open_basedir restriction in effect".
try {
symlink($to, $from);
// If module's Public is symlink.
if (is_link($to)) {
@unlink($to);
}
// Symlimk may exist but lead to the module folder in a wrong case.
// So we need first try to remove it.
if (!file_exists($from) || !is_link($from)) {
if (is_dir($from)) {
@rename($from, $from.'_'.date('YmdHis'));
} else {
@unlink($from);
}
}
if (file_exists($from)) {
return $this->info('Public symlink already exists');
}
// Check target.
if (!file_exists($to)) {
// Try to create Public folder.
try {
\File::makeDirectory($to, \Helper::DIR_PERMISSIONS);
} catch (\Exception $e) {
// If it's a broken symlink.
if (is_link($to)) {
@unlink($to);
}
}
}
try {
symlink($to, $from);
} catch (\Exception $e) {
$this->error('Error occurred creating ['.$from.' » '.$to.'] symlink: '.$e->getMessage());
}
} catch (\Exception $e) {
$this->error('Error occured creating ['.$from.'] symlink: '.$e->getMessage());
$this->error('Error occurred creating ['.$from.' » '.$to.'] symlink: '.$e->getMessage());
}
$this->info('The ['.$from.'] symlink has been created');

View File

@@ -2,9 +2,8 @@
namespace App\Console\Commands;
use Illuminate\Console\Command;
use Illuminate\Filesystem\Filesystem;
use Axn\Laroute\Routes\Collection as Routes;
use Illuminate\Console\Command;
class ModuleLaroute extends Command
{
@@ -22,6 +21,12 @@ class ModuleLaroute extends Command
*/
protected $description = 'Generate a laravel routes JS-file for a module or all modules (if module_alias is empty)';
public $routes;
public $config;
public $generator;
/**
* Create a new command instance.
*
@@ -31,8 +36,8 @@ class ModuleLaroute extends Command
{
$app = app();
$this->config = $app['config'];
$this->generator = $app->make('Lord\Laroute\Generators\GeneratorInterface');
$this->config = $app['config'];
$this->generator = $app->make('Lord\Laroute\Generators\GeneratorInterface');
parent::__construct();
}
@@ -58,6 +63,7 @@ class ModuleLaroute extends Command
}
if (!$modules_aliases) {
$this->error('No modules found');
return;
}
$all = true;
@@ -75,6 +81,7 @@ class ModuleLaroute extends Command
$module = \Module::findByAlias($module_alias);
if (!$module) {
$this->error('Module with the specified alias not found: '.$module_alias);
return;
}
$this->generateModuleRoutes($module);
@@ -88,6 +95,7 @@ class ModuleLaroute extends Command
$public_symlink = public_path('modules').DIRECTORY_SEPARATOR.$module->getAlias();
if (!file_exists($public_symlink)) {
$this->error('Public symlink ['.$public_symlink.'] not found. Run module installation command first: php artisan freescout:module-install');
return;
}
@@ -123,16 +131,15 @@ class ModuleLaroute extends Command
*/
protected function getTemplateData()
{
$namespace = $this->getOptionOrConfig('namespace');
$routes = $this->routes->toJSON();
$absolute = $this->config->get('laroute.absolute', false);
$rootUrl = $this->config->get('app.url', '');
$prefix = $this->config->get('laroute.prefix', '');
$namespace = $this->getOptionOrConfig('namespace');
$routes = $this->routes->toJSON();
$absolute = $this->config->get('laroute.absolute', false);
$rootUrl = $this->config->get('app.url', '');
$prefix = $this->config->get('laroute.prefix', '');
return compact('namespace', 'routes', 'absolute', 'rootUrl', 'prefix');
}
/**
* Get the path where the file will be generated.
*
@@ -140,7 +147,7 @@ class ModuleLaroute extends Command
*/
protected function getFileGenerationPath($module_alias)
{
$path = 'public/modules/'.$module_alias.'/js';
$path = 'public/modules/'.$module_alias.'/js';
$filename = 'laroute'; //$this->getOptionOrConfig('filename');
return "{$path}/{$filename}.js";

View File

@@ -0,0 +1,169 @@
<?php
/**
* php artisan freescout:module-install modulealias.
*/
namespace App\Console\Commands;
use Illuminate\Console\Command;
class ModuleUpdate extends Command
{
/**
* The name and signature of the console command.
*
* @var string
*/
protected $signature = 'freescout:module-update {module_alias?}';
/**
* The console command description.
*
* @var string
*/
protected $description = 'Update all modules or a single module (if module_alias is set)';
/**
* Create a new command instance.
*
* @return void
*/
public function __construct()
{
parent::__construct();
}
/**
* Execute the console command.
*
* @return mixed
*/
public function handle()
{
$install_all = false;
$modules = [];
// We have to clear modules cache first to update modules cache
\Artisan::call('cache:clear');
// Create a symlink for the module (or all modules)
$module_alias = $this->argument('module_alias');
$modules_directory = \WpApi::getModules();
if (\WpApi::$lastError) {
$this->error(__('Error occurred').': '.$lastError['message'].' ('.$lastError['code'].')');
return;
}
$installed_modules = \Module::all();
$counter = 0;
$found = false;
foreach ($modules_directory as $dir_module) {
// Update single module.
if ($module_alias && $dir_module['alias'] != $module_alias) {
continue;
}
$found = true;
// Detect if new version is available.
foreach ($installed_modules as $module) {
if ($module->getAlias() != $dir_module['alias'] /*|| !$module->active()*/) {
continue;
}
if (!empty($dir_module['version']) && version_compare($dir_module['version'], $module->get('version'), '>')) {
$update_result = \App\Module::updateModule($dir_module['alias']);
$this->info('['.$update_result['module_name'].' Module'.']');
if ($update_result['status'] == 'success') {
$this->line($update_result['msg_success']);
} else {
$msg = $update_result['msg'];
if ($update_result['download_msg']) {
$msg .= ' ('.$update_result['download_msg'].')';
}
$this->error('ERROR: '.$msg);
}
if (trim($update_result['output'])) {
$this->line(preg_replace("#\n#", "\n> ", '> '.trim($update_result['output'])));
}
$counter++;
}
}
}
// Update custom modules.
// 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) {
$this->line('All modules are up-to-date');
}
\Artisan::call('freescout:clear-cache');
}
}

View File

@@ -0,0 +1,109 @@
<?php
namespace App\Console\Commands;
use App\Mailbox;
use Webklex\PHPIMAP\IMAP;
use Webklex\PHPIMAP\Message;
use Illuminate\Console\Command;
class ParseEml extends Command
{
/**
* The name and signature of the console command.
*
* --mailbox Any mailbox able to connect via IMAP to its mail server.
*
* @var string
*/
protected $signature = 'freescout:parse-eml {--mailbox=2}';
/**
* The console command description.
*
* @var string
*/
protected $description = 'Parse EML file';
/**
* Current mailbox.
*
* Used to process emails sent to multiple mailboxes.
*/
public $mailbox;
/**
* Used to process emails sent to multiple mailboxes.
*/
public $mailboxes;
public $extra_import = [];
/**
* Page size when requesting emails from mail server.
*/
const PAGE_SIZE = 300;
/**
* Create a new command instance.
*
* @return void
*/
public function __construct()
{
parent::__construct();
}
/**
* Execute the console command.
*
* @return mixed
*/
public function handle()
{
$email = file_get_contents(storage_path('logs/email.eml'));
if (!str_contains($email, "\r\n")){
$email = str_replace("\n", "\r\n", $email);
}
$raw_header = substr($email, 0, strpos($email, "\r\n\r\n"));
$raw_body = substr($email, strlen($raw_header)+4);
$mailbox = Mailbox::find($this->option('mailbox'));
//\Config::set('app.new_fetching_library', 'true');
$client = \MailHelper::getMailboxClient($mailbox);
$client->openFolder("INBOX");
$message = Message::make(/*$this->option('uid')*/null, null, $client, $raw_header, $raw_body, [/*0 => "\\Seen"*/], IMAP::ST_UID);
$this->line('Headers: ');
$this->info($message->getHeader()->raw);
$this->line('From: ');
$this->info(json_encode($message->getFrom()[0] ?? [], JSON_UNESCAPED_UNICODE));
$this->line('Reply-To: ');
$this->info(json_encode($message->getReplyTo()[0] ?? [], JSON_UNESCAPED_UNICODE));
$this->line('In-Reply-To: ');
$this->info($message->getInReplyTo());
$this->line('References: ');
$this->info(json_encode(array_values(array_filter(preg_split('/[, <>]/', $message->getReferences() ?? ''))), JSON_UNESCAPED_UNICODE));
$this->line('Date: ');
$this->info($message->getDate());
$this->line('Subject: ');
$this->info($message->getSubject());
$this->line('Text Body: ');
$this->info($message->getTextBody());
$this->line('HTML Body: ');
$this->info($message->getHTMLBody(false));
$attachments = $message->getAttachments();
if (count($attachments)) {
$this->line('Attachments: ');
foreach ($attachments as $attachment) {
$this->info($attachment->getName());
}
}
}
}

View File

@@ -0,0 +1,66 @@
<?php
namespace App\Console\Commands;
use App\Job;
use Illuminate\Console\Command;
class SendMonitor extends Command
{
const CHECK_PERIOD = 12 * 3600; // 12 hours
/**
* The name and signature of the console command.
*
* @var string
*/
protected $signature = 'freescout:send-monitor';
/**
* The console command description.
*
* @var string
*/
protected $description = 'Check if queue:work is processing emails queue and show an alert in the web interface if needed';
/**
* Create a new command instance.
*
* @return void
*/
public function __construct()
{
parent::__construct();
}
/**
* Execute the console command.
*
* @return mixed
*/
public function handle()
{
// Get SendReplyToCustomer jobs.
$pending_jobs = \App\Job::where('queue', 'emails')
->where('payload', 'like', '{"displayName":"App\\\\\\\\Jobs\\\\\\\\SendReplyToCustomer"%')
->where('available_at', '<', time() - self::CHECK_PERIOD)
->exists();
// Check failed_jobs.
// No need - it can be done via Manage > Alerts > Logs Monitoring
// if (!$pending_jobs) {
// $pending_jobs = \App\FailedJob::where('queue', 'emails')
// ->where('payload', 'like', '{"displayName":"App\\\\\\\\Jobs\\\\\\\\SendReplyToCustomer"%')
// ->where('created_at', '<', time() - self::CHECK_PERIOD)
// ->exists();
// }
if ($pending_jobs) {
\Option::set('send_emails_problem', '1');
$this->error('['.date('Y-m-d H:i:s').'] There are problems with emails queue processing');
} else {
\Option::remove('send_emails_problem');
$this->info('['.date('Y-m-d H:i:s').'] Emails queue processing is working');
}
}
}

View File

@@ -43,18 +43,19 @@ class Update extends Command
if (!$this->confirmToProceed()) {
return;
}
@ini_set('memory_limit', '128M');
if (\Updater::isNewVersionAvailable(config('app.version'))) {
$this->info('Updating... This may take several minutes');
try {
// Script may fail here and stop with the error:
// PHP Fatal error: Allowed memory size of 94371840 bytes exhausted
\Updater::update();
$this->call('freescout:after-app-update');
} catch (\Exception $e) {
$this->error('Error occured: '.$e->getMessage());
$this->error('Error occurred: '.$e->getMessage());
}
} else {
$this->info('You have the latest version installed: '.config('app.version'));

View File

@@ -0,0 +1,46 @@
<?php
namespace App\Console\Commands;
use Illuminate\Console\Command;
class UpdateFolderCounters extends Command
{
/**
* The name and signature of the console command.
*
* @var string
*/
protected $signature = 'freescout:update-folder-counters';
/**
* The console command description.
*
* @var string
*/
protected $description = 'Update counters for all folders';
/**
* Create a new command instance.
*
* @return void
*/
public function __construct()
{
parent::__construct();
}
/**
* Execute the console command.
*
* @return mixed
*/
public function handle()
{
foreach (\App\Folder::get() as $folder) {
$folder->updateCounters();
$this->line('Updated counters for folder: '.$folder->id);
}
$this->info('Updating finished');
}
}

View File

@@ -5,9 +5,13 @@ namespace App\Console;
use Carbon\Carbon;
use Illuminate\Console\Scheduling\Schedule;
use Illuminate\Foundation\Console\Kernel as ConsoleKernel;
use App\Misc\Mail;
use App\Option;
class Kernel extends ConsoleKernel
{
const FETCH_MAX_EXECUTION_TIME = 30; // minutes
/**
* The Artisan commands provided by your application.
*
@@ -20,6 +24,7 @@ class Kernel extends ConsoleKernel
/**
* Define the application's command schedule.
* If --no-interaction flag is set the script will not run 'queue:work' daemon.
*
* @param \Illuminate\Console\Scheduling\Schedule $schedule
*
@@ -27,9 +32,14 @@ class Kernel extends ConsoleKernel
*/
protected function schedule(Schedule $schedule)
{
// https://github.com/freescout-helpdesk/freescout/issues/3970
if (!$this->isScheduleRun() && !\Helper::isRoute('system.cron')) {
return;
}
// Remove failed jobs
$schedule->command('queue:flush')
->daily();
->weekly();
// Restart processing queued jobs (just in case)
$schedule->command('queue:restart')
@@ -39,43 +49,220 @@ class Kernel extends ConsoleKernel
->everyMinute()
->withoutOverlapping();
// Fetch emails from mailboxes
$schedule->command('freescout:fetch-emails')
$schedule->command('freescout:send-monitor')
// Every 10 minutes.
->cron('*/10 * * * *')
->withoutOverlapping();
$schedule->command('freescout:update-folder-counters')
->hourly();
$app_key = config('app.key');
if ($app_key) {
$crc = crc32($app_key);
$schedule->command('freescout:module-check-licenses')
->cron((int)($crc % 59).' '.(int)($crc % 23).' * * *');
}
// Check if user finished viewing conversation.
$schedule->command('freescout:check-conv-viewers')
->everyMinute()
->withoutOverlapping()
->withoutOverlapping();
$schedule->command('freescout:clean-send-log')
->monthly();
$schedule->command('freescout:clean-notifications-table')
->weekly();
$schedule->command('freescout:clean-tmp')
->daily();
// Logs monitoring.
$alert_logs_period = config('app.alert_logs_period');
if (config('app.alert_logs') && $alert_logs_period) {
$logs_cron = '';
switch ($alert_logs_period) {
case 'hour':
$logs_cron = '0 * * * *';
break;
case 'day':
$logs_cron = '0 0 * * *';
break;
case 'week':
$logs_cron = '0 0 * * 0';
break;
case 'month':
$logs_cron = '0 0 1 * *';
break;
}
if ($logs_cron) {
$schedule->command('freescout:logs-monitor')
->cron($logs_cron)
->withoutOverlapping();
}
}
$fetch_unseen = (int)config('app.fetch_unseen');
$fetch_command_identifier = \Helper::getWorkerIdentifier('freescout:fetch-emails');
$fetch_command_name = 'freescout:fetch-emails'
. ' --identifier='.$fetch_command_identifier
. ' --unseen='.$fetch_unseen;
// Kill fetch commands running for too long.
// In shedule:run this code is executed every time $schedule->command() in this function is executed.
if (function_exists('shell_exec')) {
$fetch_command_pids = \Helper::getRunningProcesses($fetch_command_identifier);
// The name of the command here must be exactly the same as below!
// Otherwise long fetching will be killed and won't run longer than 1 mintue.
// $schedule->command() creates a new mutex, so we need to store mutex name in cache.
// $mutex_name = $schedule->command($fetch_command_name)
// ->everyMinute() - this also need to be set
// ->skip(function () {
// return true;
// })
// ->mutexName();
$mutex_name = \Cache::get('fetch_mutex_name') ?? '';
// If there is no cache mutext but there are running fetch commands
// it means the mutex had expired after self::FETCH_MAX_EXECUTION_TIME
// and the existing command(s) is running longer than self::FETCH_MAX_EXECUTION_TIME.
if (count($fetch_command_pids) > 0 && !\Cache::get($mutex_name)) {
// Kill freescout:fetch-emails commands running for too long
shell_exec('kill '.implode(' | kill ', $fetch_command_pids));
} elseif (count($fetch_command_pids) == 0) {
// Make sure 'ps' command actually works.
$ps_works = \Helper::getRunningProcesses('schedule:run');
if (count($ps_works)) {
// Previous freescout:fetch-emails may have been killed or errored and did not remove the mutex.
// So here we are forcefully removing the mutex. Otherwise mutex will live for 24 hours.
if (\Cache::has($mutex_name)) {
\Cache::forget($mutex_name);
}
}
}
}
// Fetch emails from mailboxes
$fetch_command = $schedule->command($fetch_command_name)
// withoutOverlapping() option creates a mutex in the cache
// which by default expires in 24 hours.
// So we are passing an 'expiresAt' parameter to withoutOverlapping() to
// prevent fetching from not being executed when fetching command by some reason
// does not remove the mutex from the cache.
->withoutOverlapping($expiresAt = self::FETCH_MAX_EXECUTION_TIME /* minutes */)
->sendOutputTo(storage_path().'/logs/fetch-emails.log');
switch (config('app.fetch_schedule')) {
case Mail::FETCH_SCHEDULE_EVERY_FIVE_MINUTES:
$fetch_command->everyFiveMinutes();
break;
case Mail::FETCH_SCHEDULE_EVERY_TEN_MINUTES:
$fetch_command->everyTenMinutes();
break;
case Mail::FETCH_SCHEDULE_EVERY_FIFTEEN_MINUTES:
$fetch_command->everyFifteenMinutes();
break;
case Mail::FETCH_SCHEDULE_EVERY_THIRTY_MINUTES:
$fetch_command->everyThirtyMinutes();
break;
case Mail::FETCH_SCHEDULE_HOURLY:
$fetch_command->Hourly();
break;
default:
$fetch_command->everyMinute();
break;
}
\Cache::put('fetch_mutex_name', $fetch_command->mutexName(), self::FETCH_MAX_EXECUTION_TIME);
$schedule = \Eventy::filter('schedule', $schedule);
// If --no-daemonize flag is passed - do not run 'queue:work' daemon.
foreach ($_SERVER['argv'] ?? [] as $arg) {
if ($arg == '--no-interaction') {
return;
}
}
// Command runs as subprocess and sets cache mutex. If schedule:run command is killed
// subprocess does not clear the mutex and it stays in the cache until cache:clear is executed.
// By default, the lock will expire after 24 hours.
//
// cache:clear clears the mutex, but sometimes process continues running, so we need to kill it.
$queue_work_params = Config('app.queue_work_params');
// Add identifier to avoid conflicts with other FreeScout instances on the same server.
$queue_work_params['--queue'] .= ','.\Helper::getWorkerIdentifier();
// $schedule->command('queue:work') command below has withoutOverlapping() option,
// which works via special mutex stored in the cache preventing several 'queue:work' to work at the same time.
// So when the cache is cleared the mutex indicating that the 'queue:work' is running is removed,
// and the second 'queue:work' command is launched by cron. When `artisan schedule:run` is executed it sees
// that there are two 'queue:work' processes running and kills them.
// After one minute 'queue:work' is executed by cron via `artisan schedule:run` and works in the background.
if (function_exists('shell_exec')) {
$running_commands = 0;
try {
$processes = preg_split("/[\r\n]/", shell_exec("ps aux | grep 'queue:work'"));
foreach ($processes as $process) {
preg_match("/^[\S]+\s+([\d]+)\s+/", $process, $m);
if (!preg_match("/(sh \-c|grep )/", $process) && !empty($m[1])) {
$running_commands++;
$running_commands = \Helper::getRunningProcesses();
if (count($running_commands) > 1) {
// Stop all queue:work processes.
// queue:work command is stopped by settings a cache key
\Helper::queueWorkerRestart();
// Sometimes processes stuck and just continue running, so we need to kill them.
// Sleep to let processes stop.
sleep(1);
// Check processes again.
$worker_pids = \Helper::getRunningProcesses();
if (count($worker_pids) > 1) {
// Current process also has to be killed, as otherwise it "stucks"
// $current_pid = getmypid();
// foreach ($worker_pids as $i => $pid) {
// if ($pid == $current_pid) {
// unset($worker_pids[$i]);
// break;
// }
// }
shell_exec('kill '.implode(' | kill ', $worker_pids));
}
} elseif (count($running_commands) == 0) {
// Make sure 'ps' command actually works.
$ps_works = \Helper::getRunningProcesses('schedule:run');
if (count($ps_works)) {
// Previous queue:work may have been killed or errored and did not remove the mutex.
// So here we are forcefully removing the mutex.
$mutex_name = $schedule->command('queue:work', $queue_work_params)
->skip(function () {
return true;
})
->mutexName();
if (\Cache::get($mutex_name)) {
\Cache::forget($mutex_name);
}
}
} catch (\Exception $e) {
// Do nothing
}
if ($running_commands > 1) {
// queue:work command is stopped by settings a cache key
\Cache::forever('illuminate:queue:restart', Carbon::now()->getTimestamp());
}
}
$schedule->command('queue:work', Config('app.queue_work_params'))
$schedule->command('queue:work', $queue_work_params)
->everyMinute()
->withoutOverlapping()
->sendOutputTo(storage_path().'/logs/queue-jobs.log');
}
/**
* This function is needed because every time $schedule->command() is executed
* the schedule() is executed also.
*/
public function isScheduleRun()
{
if (\Helper::isConsole()) {
return true;
} else {
return !empty($_SERVER['argv']) && in_array('schedule:run', $_SERVER['argv']);
}
}
/**
* Register the commands for the application.
*
@@ -85,6 +272,13 @@ class Kernel extends ConsoleKernel
{
$this->load(__DIR__.'/Commands');
// Swiftmailer uses $_SERVER['SERVER_NAME'] in transport_deps.php
// to set the host for EHLO command, if it is empty it uses [127.0.0.1].
// G Suite sometimes rejects emails with EHLO [127.0.0.1].
if (empty($_SERVER['SERVER_NAME'])) {
$_SERVER['SERVER_NAME'] = parse_url(config('app.url'), PHP_URL_HOST);
}
require base_path('routes/console.php');
}
}

File diff suppressed because it is too large Load Diff

View File

@@ -3,11 +3,10 @@
namespace App;
use Illuminate\Database\Eloquent\Model;
use Illuminate\Support\Facades\Input;
class ConversationFolder extends Model
{
/**
/**
* The table associated with the model.
*
* @var string
@@ -15,4 +14,4 @@ class ConversationFolder extends Model
protected $table = 'conversation_folder';
protected $fillable = ['folder_id', 'conversation_id'];
}
}

File diff suppressed because it is too large Load Diff

58
app/CustomerChannel.php Normal file
View File

@@ -0,0 +1,58 @@
<?php
namespace App;
use Illuminate\Database\Eloquent\Model;
class CustomerChannel extends Model
{
/**
* The table associated with the model.
*
* @var string
*/
protected $table = 'customer_channel';
public $timestamps = false;
/**
* Cached communication channels.
*/
public static $channels = null;
public function customer()
{
return $this->belongsTo('App\Customer');
}
public static function create($customer_id, $channel, $channel_id)
{
try {
$customer_channel = new self();
$customer_channel->customer_id = $customer_id;
$customer_channel->channel = $channel;
$customer_channel->channel_id = $channel_id;
$customer_channel->save();
return $customer_channel;
} catch (\Exception $e) {
// Already exists.
return null;
}
}
public function getChannelName()
{
return \Eventy::filter('channel.name', '', $this->channel);
}
public static function getChannels()
{
if (self::$channels !== null) {
return self::$channels;
} else {
self::$channels = \Eventy::filter('channels.list', []);
return self::$channels;
}
}
}

View File

@@ -3,9 +3,14 @@
namespace App;
use Illuminate\Database\Eloquent\Model;
use Watson\Rememberable\Rememberable;
class Email extends Model
{
use Rememberable;
// This is obligatory.
public $rememberCacheDriver = 'array';
/**
* Email types.
*/
@@ -47,11 +52,15 @@ class Email extends Model
// Email validation is not recommended:
// http://stackoverflow.com/questions/201323/using-a-regular-expression-to-validate-an-email-address/201378#201378
// So we just check for @
if (!preg_match('/@/', $email)) {
if (!preg_match('/^.+@.+$/', $email ?? '')) {
return false;
}
$email = filter_var($email, FILTER_SANITIZE_EMAIL);
$email = mb_strtolower($email, 'UTF-8');
// Remove trailing dots.
$email = preg_replace("/\.+$/", '', $email);
// Remove dot before @
$email = preg_replace("/\.+@/", '@', $email);
return $email;
}
@@ -60,4 +69,19 @@ class Email extends Model
{
return explode('@', $this->email)[0];
}
public static function create($email, $customer_id, $type = self::TYPE_WORK)
{
try {
$email_obj = new Email();
$email_obj->email = $email;
$email_obj->type = array_key_exists($type, self::$types) ? $type : self::TYPE_WORK;
$email_obj->customer_id = $customer_id;
$email_obj->save();
return $email_obj;
} catch (\Exception $e) {
return null;
}
}
}

View File

@@ -3,17 +3,15 @@
namespace App\Events;
use Illuminate\Broadcasting\Channel;
use Illuminate\Queue\SerializesModels;
use Illuminate\Broadcasting\PrivateChannel;
use Illuminate\Broadcasting\PresenceChannel;
use Illuminate\Broadcasting\InteractsWithSockets;
use Illuminate\Contracts\Broadcasting\ShouldBroadcastNow;
use Illuminate\Queue\SerializesModels;
class RealtimeBroadcastNotificationCreated implements ShouldBroadcastNow
{
use SerializesModels;
/**
/**
* The notifiable entity who received the notification.
*
* @var mixed
@@ -55,7 +53,7 @@ class RealtimeBroadcastNotificationCreated implements ShouldBroadcastNow
{
$channels = $this->notification->broadcastOn();
if (! empty($channels)) {
if (!empty($channels)) {
return $channels;
}
@@ -72,7 +70,7 @@ class RealtimeBroadcastNotificationCreated implements ShouldBroadcastNow
public function broadcastWith()
{
return array_merge($this->data, [
'id' => $this->notification->id,
'id' => $this->notification->id,
'type' => get_class($this->notification),
]);
// return [
@@ -95,4 +93,4 @@ class RealtimeBroadcastNotificationCreated implements ShouldBroadcastNow
return $class.'.'.$this->notifiable->getKey();
}
}
}

102
app/Events/RealtimeChat.php Normal file
View File

@@ -0,0 +1,102 @@
<?php
/**
* Fefresh chats list when new thread created in mailbox.
*/
namespace App\Events;
use App\Conversation;
use App\Mailbox;
use Illuminate\Broadcasting\Channel;
use Illuminate\Broadcasting\PrivateChannel;
use Illuminate\Contracts\Broadcasting\ShouldBroadcastNow;
use Illuminate\Queue\SerializesModels;
class RealtimeChat implements ShouldBroadcastNow
{
use SerializesModels;
/**
* The notification data.
*
* @var array
*/
public $data = [];
/**
* Create a new event instance.
*
* @return void
*/
public function __construct($data)
{
$this->data = $data;
}
/**
* Get the channels the event should broadcast on.
*
* @return Channel|array
*/
public function broadcastOn()
{
return new \Illuminate\Broadcasting\Channel($this->channelName());
}
/**
* Get the data to broadcast.
*
* @return array
*/
public function broadcastWith()
{
return $this->data;
}
/**
* Get the broadcast channel name for the event.
*
* @return string
*/
protected function channelName()
{
if (!empty($this->data['mailbox_id'])) {
return 'chat.'.$this->data['mailbox_id'];
} else {
return 'chat.0';
}
}
/**
* Helper funciton.
*/
public static function dispatchSelf($mailbox_id)
{
if (!\Helper::isChatModeAvailable()) {
return;
}
$notification_data = [
'mailbox_id' => $mailbox_id
];
event(new \App\Events\RealtimeChat($notification_data));
}
public static function processPayload($payload)
{
$user = auth()->user();
$mailbox = Mailbox::rememberForever()->find($payload->mailbox_id);
// Check if user can listen to this event.
if (!$user || !$mailbox || !$user->can('viewCached', $mailbox)) {
return [];
}
// Chats are retrieved in the template.
$template_data = [
'mailbox' => $mailbox,
];
$payload->chats_html = \View::make('mailboxes/partials/chat_list')->with($template_data)->render();
return $payload;
}
}

View File

@@ -0,0 +1,118 @@
<?php
/**
* New thread created in conversation.
*/
namespace App\Events;
use App\Conversation;
use App\Mailbox;
use App\Thread;
use Illuminate\Broadcasting\Channel;
use Illuminate\Broadcasting\PrivateChannel;
use Illuminate\Contracts\Broadcasting\ShouldBroadcastNow;
use Illuminate\Queue\SerializesModels;
class RealtimeConvNewThread implements ShouldBroadcastNow
{
use SerializesModels;
/**
* The notification data.
*
* @var array
*/
public $data = [];
/**
* Create a new event instance.
*
* @return void
*/
public function __construct($data)
{
$this->data = $data;
}
/**
* Get the channels the event should broadcast on.
*
* @return Channel|array
*/
public function broadcastOn()
{
return new \Illuminate\Broadcasting\Channel($this->channelName());
}
/**
* Get the data to broadcast.
*
* @return array
*/
public function broadcastWith()
{
return $this->data;
}
/**
* Get the broadcast channel name for the event.
*
* @return string
*/
protected function channelName()
{
if (!empty($this->data['conversation_id'])) {
return 'conv.'.$this->data['conversation_id'];
} else {
return 'conv.0';
}
}
/**
* Helper funciton.
*/
public static function dispatchSelf($thread)
{
if ($thread->state != Thread::STATE_PUBLISHED) {
return;
}
$notification_data = [
'thread_id' => $thread->id,
'conversation_id' => $thread->conversation_id,
// conversation is prefetched in ThreadObserver.
'mailbox_id' => $thread->conversation->mailbox_id,
//'user_id' => $thread->created_by_user_id,
];
event(new \App\Events\RealtimeConvNewThread($notification_data));
}
public static function processPayload($payload)
{
$user = auth()->user();
$mailbox = Mailbox::rememberForever()->find($payload->mailbox_id);
// Check if user can listen to this event.
if (!$user || !$mailbox || !$user->can('viewCached', $mailbox)) {
return [];
}
$thread = Thread::find($payload->thread_id);
if (!$thread) {
return $payload;
}
// Add thread html to the payload.
$template_data = [
'conversation' => $thread->conversation,
'mailbox' => $thread->conversation->mailbox,
'threads' => [$thread],
];
$payload->thread_html = \View::make('conversations/partials/threads')->with($template_data)->render();
$payload->conversation_user_id = $thread->conversation->user_id;
$payload->conversation_status = $thread->conversation->status;
$payload->conversation_status_class = Conversation::$status_classes[$thread->conversation->status];
$payload->conversation_status_icon = Conversation::$status_icons[$thread->conversation->status];
return $payload;
}
}

View File

@@ -0,0 +1,113 @@
<?php
namespace App\Events;
use Illuminate\Broadcasting\Channel;
//use Illuminate\Broadcasting\PrivateChannel;
use Illuminate\Contracts\Broadcasting\ShouldBroadcastNow;
use Illuminate\Queue\SerializesModels;
class RealtimeConvView implements ShouldBroadcastNow
{
use SerializesModels;
/**
* The notifiable entity who received the notification.
*
* @var mixed
*/
//public $notifiable;
/**
* The notification instance.
*
* @var \Illuminate\Notifications\Notification
*/
//public $notification;
/**
* The notification data.
*
* @var array
*/
public $data = [];
/**
* Create a new event instance.
*
* @return void
*/
public function __construct(/*$notifiable, $notification,*/ $data)
{
$this->data = $data;
// $this->notifiable = $notifiable;
// $this->notification = $notification;
}
/**
* Get the channels the event should broadcast on.
*
* @return Channel|array
*/
public function broadcastOn()
{
// $channels = $this->notification->broadcastOn();
// if (!empty($channels)) {
// return $channels;
// }
return new \Illuminate\Broadcasting\Channel($this->channelName());
//return [new PrivateChannel()];
}
/**
* Get the data to broadcast.
*
* @return array
*/
public function broadcastWith()
{
return $this->data;
/*return array_merge($this->data, [
'id' => $this->notification->id,
'type' => get_class($this->notification),
]);*/
}
/**
* Get the broadcast channel name for the event.
*
* @return string
*/
protected function channelName()
{
// if (method_exists($this->notifiable, 'receivesBroadcastNotificationsOn')) {
// return $this->notifiable->receivesBroadcastNotificationsOn($this->notification);
// }
return 'conv';
// $class = str_replace('\\', '.', get_class($this->notifiable));
// return $class.'.'.$this->notifiable->getKey();
}
/**
* Helper funciton.
*/
public static function dispatchSelf($conversation_id, $user, $replying = false)
{
$notification_data = [
'conversation_id' => $conversation_id,
'user_id' => $user->id,
'user_photo_url' => $user->getPhotoUrl(false),
// These has to be encoded to avoid "Unable to JSON encode payload. Error code: 5"
'user_initials' => htmlentities($user->getInitials()),
'user_name' => htmlentities($user->getFullName()),
'replying' => (int)$replying,
];
event(new \App\Events\RealtimeConvView($notification_data));
}
}

View File

@@ -0,0 +1,62 @@
<?php
/**
* User finished viewing conversatin.
*/
namespace App\Events;
use Illuminate\Broadcasting\Channel;
use Illuminate\Broadcasting\PrivateChannel;
use Illuminate\Contracts\Broadcasting\ShouldBroadcastNow;
use Illuminate\Queue\SerializesModels;
class RealtimeConvViewFinish implements ShouldBroadcastNow
{
use SerializesModels;
/**
* The notification data.
*
* @var array
*/
public $data = [];
/**
* Create a new event instance.
*
* @return void
*/
public function __construct($data)
{
$this->data = $data;
}
/**
* Get the channels the event should broadcast on.
*
* @return Channel|array
*/
public function broadcastOn()
{
return new \Illuminate\Broadcasting\Channel($this->channelName());
}
/**
* Get the data to broadcast.
*
* @return array
*/
public function broadcastWith()
{
return $this->data;
}
/**
* Get the broadcast channel name for the event.
*
* @return string
*/
protected function channelName()
{
return 'conv';
}
}

View File

@@ -0,0 +1,110 @@
<?php
/**
* New thread created in mailbox.
*/
namespace App\Events;
use App\Conversation;
use App\Mailbox;
use App\Folder;
use Illuminate\Broadcasting\Channel;
use Illuminate\Broadcasting\PrivateChannel;
use Illuminate\Contracts\Broadcasting\ShouldBroadcastNow;
use Illuminate\Queue\SerializesModels;
class RealtimeMailboxNewThread implements ShouldBroadcastNow
{
use SerializesModels;
/**
* The notification data.
*
* @var array
*/
public $data = [];
/**
* Create a new event instance.
*
* @return void
*/
public function __construct($data)
{
$this->data = $data;
}
/**
* Get the channels the event should broadcast on.
*
* @return Channel|array
*/
public function broadcastOn()
{
return new \Illuminate\Broadcasting\Channel($this->channelName());
}
/**
* Get the data to broadcast.
*
* @return array
*/
public function broadcastWith()
{
return $this->data;
}
/**
* Get the broadcast channel name for the event.
*
* @return string
*/
protected function channelName()
{
if (!empty($this->data['mailbox_id'])) {
return 'mailbox.'.$this->data['mailbox_id'];
} else {
return 'mailbox.0';
}
}
/**
* Helper funciton.
*/
public static function dispatchSelf($mailbox_id)
{
$notification_data = [
'mailbox_id' => $mailbox_id
];
event(new \App\Events\RealtimeMailboxNewThread($notification_data));
}
public static function processPayload($payload)
{
$user = auth()->user();
$mailbox = Mailbox::rememberForever()->find($payload->mailbox_id);
// Check if user can listen to this event.
if (!$user || !$mailbox || !$user->can('viewCached', $mailbox)) {
return [];
}
$folder = null;
$foler_id = Conversation::getFolderParam();
if ($foler_id) {
$folder = Folder::find($foler_id);
}
// Just in case.
if (!$folder) {
$folder = new Folder();
}
$template_data = [
'folders' => $mailbox->getAssesibleFolders(),
'folder' => $folder,
'mailbox' => $mailbox,
];
$payload->folders_html = \View::make('mailboxes/partials/folders')->with($template_data)->render();
return $payload;
}
}

View File

@@ -6,7 +6,7 @@ use App\User;
class UserDeleted
{
public $user;
public $by_user;
public $deleted_user;
/**
@@ -14,9 +14,11 @@ class UserDeleted
*
* @return void
*/
public function __construct(User $user, User $deleted_user)
public function __construct(User $deleted_user, User $by_user)
{
$this->user = $user;
$this->by_user = $by_user;
$this->deleted_user = $deleted_user;
\Eventy::action('user.deleted', $deleted_user, $by_user);
}
}

View File

@@ -10,4 +10,27 @@ class FailedJob extends Model
* Automatically converted into Carbon dates.
*/
protected $dates = ['failed_at'];
public $payload_decoded = null;
public function getPayloadDecoded()
{
if ($this->payload_decoded !== null) {
return $this->payload_decoded;
}
$this->payload_decoded = json_decode($this->payload, true);
return $this->payload_decoded;
}
public function getCommand()
{
return \App\Job::getPayloadCommand($this->getPayloadDecoded());
}
public static function retry($job_id)
{
\Artisan::call('queue:retry', ['id' => $job_id]);
}
}

View File

@@ -17,18 +17,18 @@ class Folder extends Model
const TYPE_DRAFTS = 30;
const TYPE_ASSIGNED = 40;
const TYPE_CLOSED = 60;
const TYPE_DELETED = 70;
const TYPE_SPAM = 80;
const TYPE_DELETED = 110;
public static $types = [
self::TYPE_UNASSIGNED => 'Unassigned',
self::TYPE_MINE => 'Mine',
self::TYPE_STARRED => 'Starred',
self::TYPE_DRAFTS => 'Drafts',
self::TYPE_ASSIGNED => 'Assigned',
self::TYPE_CLOSED => 'Closed',
self::TYPE_SPAM => 'Spam',
self::TYPE_DELETED => 'Deleted',
self::TYPE_STARRED => 'Starred',
];
/**
@@ -68,8 +68,16 @@ class Folder extends Model
self::TYPE_STARRED,
];
// Counter mode.
const COUNTER_ACTIVE = 1;
const COUNTER_TOTAL = 2;
public $timestamps = false;
protected $casts = [
'meta' => 'array',
];
/**
* Get the mailbox to which folder belongs.
*/
@@ -96,12 +104,32 @@ class Folder extends Model
public function getTypeName()
{
return __(self::$types[$this->type]);
// To make name translatable.
switch ($this->type) {
case self::TYPE_UNASSIGNED:
return __('Unassigned');
case self::TYPE_MINE:
return __('Mine');
case self::TYPE_DRAFTS:
return __('Drafts');
case self::TYPE_ASSIGNED:
return __('Assigned');
case self::TYPE_CLOSED:
return __('Closed');
case self::TYPE_SPAM:
return __('Spam');
case self::TYPE_DELETED:
return __('Deleted');
case self::TYPE_STARRED:
return __('Starred');
default:
return __(\Eventy::filter('folder.type_name', self::$types[$this->type] ?? '', $this));
}
}
public function getTypeIcon()
{
return self::$type_icons[$this->type];
return \Eventy::filter('folder.type_icon', self::$type_icons[$this->type] ?? '', $this);
}
/**
@@ -124,7 +152,6 @@ class Folder extends Model
case self::TYPE_STARRED:
$order_by[] = ['status' => 'asc'];
$order_by[] = ['last_reply_at' => 'desc'];
//$order_by = [['conversation_folder.id' => 'desc']];
break;
case self::TYPE_DRAFTS:
@@ -133,6 +160,7 @@ class Folder extends Model
case self::TYPE_CLOSED:
$order_by = [['closed_at' => 'desc']];
break;
case self::TYPE_SPAM:
$order_by = [['last_reply_at' => 'desc']];
@@ -141,6 +169,30 @@ class Folder extends Model
case self::TYPE_DELETED:
$order_by = [['user_updated_at' => 'desc']];
break;
default:
$order_by = \Eventy::filter('folder.conversations_order_by', $order_by, $this->type);
break;
}
// Process columns sorting.
$sorting = Conversation::getConvTableSorting();
if ($sorting['sort_by'] == 'date') {
if ($sorting['order'] != 'desc') {
foreach ($order_by as $block_i => $block) {
foreach ($block as $field => $order) {
if ($field == 'status') {
unset($order_by[$block_i][$field]);
} else {
if ($order == 'desc') {
$order_by[$block_i][$field] = 'asc';
}
}
}
}
}
} else {
$order_by = [[$sorting['sort_by'] => $sorting['order']]];
}
return $order_by;
@@ -166,31 +218,49 @@ class Folder extends Model
*/
public function isIndirect()
{
return in_array($this->type, Folder::$indirect_types);
return in_array($this->type, self::$indirect_types);
}
public function updateCounters()
{
if ($this->type == Folder::TYPE_MINE && $this->user_id) {
if (config('app.update_folder_counters_in_background')) {
if(!\Illuminate\Support\Facades\Cache::has("folder_update_lock_{$this->id}")) {
\App\Jobs\UpdateFolderCounters::dispatch($this);
}
} else {
$this->updateCountersNow();
}
}
public function updateCountersNow()
{
if (\Eventy::filter('folder.update_counters', false, $this)) {
return;
}
if ($this->type == self::TYPE_MINE && $this->user_id) {
$this->active_count = Conversation::where('user_id', $this->user_id)
->where('mailbox_id', $this->mailbox_id)
->where('status', Conversation::STATUS_ACTIVE)
->where('state', Conversation::STATE_PUBLISHED)
->where('status', Conversation::STATUS_ACTIVE)
->count();
$this->total_count = Conversation::where('user_id', $this->user_id)
->where('mailbox_id', $this->mailbox_id)
->where('state', Conversation::STATE_PUBLISHED)
->count();
} elseif ($this->type == Folder::TYPE_STARRED) {
} elseif ($this->type == self::TYPE_STARRED) {
$this->active_count = count(Conversation::getUserStarredConversationIds($this->mailbox_id, $this->user_id));
$this->total_count = $this->active_count;
} elseif ($this->type == Folder::TYPE_DELETED) {
} elseif ($this->type == self::TYPE_DELETED) {
$this->active_count = $this->conversations()->where('state', Conversation::STATE_DELETED)
->count();
$this->total_count = $this->active_count;
} elseif ($this->isIndirect()) {
// Conversation are connected to folder via conversation_folder table.
$this->active_count = ConversationFolder::where('folder_id', $this->id)->count();
// Drafts.
$this->active_count = ConversationFolder::where('conversation_folder.folder_id', $this->id)
->join('conversations', 'conversations.id', '=', 'conversation_folder.conversation_id')
//->where('state', Conversation::STATE_PUBLISHED)
->count();
$this->total_count = $this->active_count;
} else {
$this->active_count = $this->conversations()
@@ -204,19 +274,46 @@ class Folder extends Model
$this->save();
}
/**
* Get count to display in folders list.
*
* @param array $folders [description]
*
* @return [type] [description]
*/
public function getCount($folders = [])
{
$counter = \Eventy::filter('folder.counter', self::COUNTER_ACTIVE, $this, $folders);
$count = \Eventy::filter('folder.count', false, $this, $counter, $folders);
if ($count !== false) {
return $count;
}
if ($counter == self::COUNTER_TOTAL || $this->type == self::TYPE_STARRED || $this->type == self::TYPE_DRAFTS) {
return $this->total_count;
} else {
return $this->getActiveCount($folders);
}
}
/**
* Get calculated number of active conversations.
*/
public function getActiveCount($folders = [])
{
$active_count = $this->active_count;
if ($this->type == Folder::TYPE_ASSIGNED) {
if ($folders) {
$mine_folder = $folders->firstWhere('type', Folder::TYPE_MINE);
} else {
$mine_folder = $this->mailbox->folders()->where('type', Folder::TYPE_MINE)->first();
if ($this->type == self::TYPE_ASSIGNED) {
$mine_folder = \Eventy::filter('folder.active_count_mine_folder', null, $this, $folders);
if (!$mine_folder) {
if ($folders) {
$mine_folder = $folders->firstWhere('type', self::TYPE_MINE);
} elseif ($this->mailbox_id) {
$mine_folder = $this->mailbox->folders()->where('type', self::TYPE_MINE)->first();
}
}
if ($mine_folder) {
$active_count = $active_count - $mine_folder->active_count;
if ($active_count < 0) {
@@ -227,4 +324,135 @@ class Folder extends Model
return $active_count;
}
/**
* Query for waiting since.
*/
public function getWaitingSinceQuery()
{
$query = null;
if ($this->type == self::TYPE_MINE) {
// Assigned to user.
$query = Conversation::where('user_id', $this->user_id)
->where('mailbox_id', $this->mailbox_id);
} elseif ($this->isIndirect()) {
// Via intermediate table.
$query = Conversation::join('conversation_folder', 'conversations.id', '=', 'conversation_folder.conversation_id')
->where('conversation_folder.folder_id', $this->id);
} else {
// All other conversations.
$query = $this->conversations();
}
return \Eventy::filter('folder.waiting_since_query', $query, $this);
}
/**
* Works for main folder only for now.
*
* @return [type] [description]
*/
public function getWaitingSince()
{
// Get oldest active conversation.
$conversation = $this->getWaitingSinceQuery()
->where('state', Conversation::STATE_PUBLISHED)
->where('status', Conversation::STATUS_ACTIVE)
->orderBy($this->getWaitingSinceField(), 'asc')
->first();
if ($conversation) {
return $conversation->getWaitingSince($this);
} else {
return '';
}
}
/**
* Get conversation field used to detect waiting since time.
*
* @return [type] [description]
*/
public function getWaitingSinceField()
{
if ($this->type == \App\Folder::TYPE_CLOSED) {
return 'closed_at';
} elseif ($this->type == \App\Folder::TYPE_DRAFTS) {
return 'updated_at';
} elseif ($this->type == \App\Folder::TYPE_DELETED) {
return 'user_updated_at';
} else {
return'last_reply_at';
}
}
public function url($mailbox_id)
{
return \Eventy::filter('folder.url', route('mailboxes.view.folder', ['id'=>$mailbox_id, 'folder_id'=>$this->id]), $mailbox_id, $this);
}
public static function create($data, $unique_per_user = true, $save = true)
{
if (!isset($data['mailbox_id']) || !isset($data['type'])) {
return null;
}
$folder = new Folder ();
$folder->mailbox_id = $data['mailbox_id'];
$folder->type = $data['type'];
if (!empty($data['user_id'])) {
if ($unique_per_user) {
$user_folder = Folder::where('mailbox_id', $data['mailbox_id'])
->where('user_id', $data['user_id'])
->where('type', $data['type'])
->first();
// User folder already exists.
if ($user_folder) {
return $user_folder;
}
}
$folder->user_id = $data['user_id'];
}
if ($save) {
$folder->save();
}
return $folder;
}
/**
* Get meta value.
*/
public function getMeta($key, $default = null)
{
$metas = $this->meta;
if (isset($metas[$key])) {
return $metas[$key];
} else {
return $default;
}
}
/**
* Set meta value.
*/
public function setMeta($key, $value)
{
$metas = $this->meta;
$metas[$key] = $value;
$this->meta = $metas;
}
/**
* Unset thread meta value.
*/
public function unsetMeta($key)
{
$metas = $this->meta;
if (isset($metas[$key])) {
unset($metas[$key]);
$this->meta = $metas;
}
}
}

10
app/Follower.php Normal file
View File

@@ -0,0 +1,10 @@
<?php
namespace App;
use Illuminate\Database\Eloquent\Model;
class Follower extends Model
{
public $timestamps = false;
}

View File

@@ -2,8 +2,10 @@
namespace App\Http\Controllers\Auth;
use Illuminate\Http\Request;
use App\Http\Controllers\Controller;
use Illuminate\Foundation\Auth\AuthenticatesUsers;
use Illuminate\Validation\ValidationException;
class LoginController extends Controller
{
@@ -25,7 +27,9 @@ class LoginController extends Controller
*
* @var string
*/
protected $redirectTo = '/';
protected $redirectTo = '/home';
public $decayMinutes = 10; // minutes to lockout
/**
* Create a new controller instance.
@@ -36,4 +40,40 @@ class LoginController extends Controller
{
$this->middleware('guest')->except('logout');
}
/**
* Handle a login request to the application.
*
* @param \Illuminate\Http\Request $request
* @return \Illuminate\Http\RedirectResponse|\Illuminate\Http\Response|\Illuminate\Http\JsonResponse
*/
public function login(Request $request)
{
$this->validateLogin($request);
// If the class is using the ThrottlesLogins trait, we can automatically throttle
// the login attempts for this application. We'll key this by the username and
// the IP address of the client making these requests into this application.
if ($this->hasTooManyLoginAttempts($request)) {
$this->fireLockoutEvent($request);
return $this->sendLockoutResponse($request);
}
$custom_errors = \Eventy::filter('login.custom_check', [], $request);
if ($custom_errors) {
throw ValidationException::withMessages($custom_errors);
}
if ($this->attemptLogin($request)) {
return $this->sendLoginResponse($request);
}
// If the login attempt was unsuccessful we will increment the number of attempts
// to login and redirect the user back to the login form. Of course, when this
// user surpasses their maximum number of attempts they will get locked out.
$this->incrementLoginAttempts($request);
return $this->sendFailedLoginResponse($request);
}
}

View File

@@ -4,6 +4,9 @@ namespace App\Http\Controllers\Auth;
use App\Http\Controllers\Controller;
use Illuminate\Foundation\Auth\ResetsPasswords;
use Illuminate\Support\Str;
use Illuminate\Support\Facades\Hash;
use Illuminate\Auth\Events\PasswordReset;
class ResetPasswordController extends Controller
{
@@ -36,4 +39,24 @@ class ResetPasswordController extends Controller
{
$this->middleware('guest');
}
/**
* Reset the given user's password.
*
* @param \Illuminate\Contracts\Auth\CanResetPassword $user
* @param string $password
* @return void
*/
protected function resetPassword($user, $password)
{
$user->password = Hash::make($password);
$user->setRememberToken(Str::random(60));
$user->save();
event(new PasswordReset($user));
//$this->guard()->login($user);
}
}

2477
app/Http/Controllers/ConversationsController.php Normal file → Executable file

File diff suppressed because it is too large Load Diff

View File

@@ -6,7 +6,6 @@ use App\Conversation;
use App\Customer;
use App\Email;
use Illuminate\Http\Request;
use Illuminate\Support\Collection;
use Validator;
class CustomersController extends Controller
@@ -68,12 +67,26 @@ class CustomersController extends Controller
//'emails' => 'array|required_without:first_name',
//'emails.1' => 'nullable|email|required_without:first_name',
'emails.*' => 'nullable|email|distinct|required_without:first_name',
'photo_url' => 'nullable|image|mimes:jpeg,png,jpg,gif',
]);
$validator->setAttributeNames([
//'emails.1' => __('Email'),
'photo_url' => __('Photo'),
'emails.*' => __('Email'),
]);
// Photo
$validator->after(function ($validator) use ($customer, $request) {
if ($request->hasFile('photo_url')) {
$path_url = $customer->savePhoto($request->file('photo_url')->getRealPath() ?: $request->file('photo_url')->getPathname(), $request->file('photo_url')->getMimeType());
if ($path_url) {
$customer->photo_url = $path_url;
} else {
$validator->errors()->add('photo_url', __('Error occurred processing the image. Make sure that PHP GD extension is enabled.'));
}
}
});
if ($validator->fails()) {
return redirect()->route('customers.update', ['id' => $id])
->withErrors($validator)
@@ -96,12 +109,12 @@ class CustomersController extends Controller
foreach ($new_emails as $new_email) {
$email = Email::where('email', $new_email)->first();
if ($email && $email->customer) {
// If customer whose email is removed does not have first name and other emails
// If customer whose email is removed does not have first name and other emails
// we have to create first name for this customer
if (!$email->customer->first_name && count($email->customer->emails) == 1) {
if ($request->first_name) {
$email->customer->first_name = $request->first_name;
} else if ($customer->first_name) {
} elseif ($customer->first_name) {
$email->customer->first_name = $customer->first_name;
} else {
$email->customer->first_name = mb_ucfirst($email->getNameFromEmail());
@@ -110,15 +123,15 @@ class CustomersController extends Controller
}
$flash_message .= __('Email :tag_email_begin:email:tag_email_end has been moved from another customer: :a_begin:customer:a_end.', [
'email' => $email->email,
'email' => $email->email,
'tag_email_begin' => '<strong>',
'tag_email_end' => '</strong>',
'customer' => $email->customer->getFullName(),
'a_begin' => '<strong><a href="'.$email->customer->url().'" target="_blank">',
'a_end' => '</a></strong>',
'tag_email_end' => '</strong>',
'customer' => $email->customer->getFullName(),
'a_begin' => '<strong><a href="'.$email->customer->url().'" target="_blank">',
'a_end' => '</a></strong>',
]).' ';
$new_emails_change_customer[] = $email->email;
$new_emails_change_customer[] = $email;
}
}
@@ -129,26 +142,37 @@ class CustomersController extends Controller
}
}
$customer->fill($request->all());
// Websites
if (!empty($request->websites)) {
$customer->setWebsites($request->websites);
$request_data = $request->all();
if (isset($request_data['photo_url'])) {
unset($request_data['photo_url']);
}
$customer->setData($request_data);
// Websites
// if (!empty($request->websites)) {
// $customer->setWebsites($request->websites);
// }
$customer->save();
$customer->syncEmails($request->emails);
// Update customer_id in all conversations to the current customer
// Update customer_id in all conversations added to the current customer.
foreach ($new_emails_change_customer as $new_email) {
$conversations_to_change_customer = Conversation::where('customer_email', $new_email)->get();
if ($new_email->customer_id) {
$conversations_to_change_customer = Conversation::where('customer_id', $new_email->customer_id)->get();
} else {
// This does not work for phone conversations.
$conversations_to_change_customer = Conversation::where('customer_email', $new_email->email)->get();
}
foreach ($conversations_to_change_customer as $conversation) {
// We have to pass user to create line item and let others know that customer has changed.
// Conversation may be even in other mailbox where user does not have an access.
$conversation->changeCustomer($new_email, $customer, auth()->user());
$conversation->changeCustomer($new_email->email, $customer, auth()->user());
}
}
// Update customer in conversations for removed emails
// Update customer in conversations for emails removed from current customer.
foreach ($removed_emails as $removed_email) {
$email = Email::where('email', $removed_email)->first();
if ($email) {
@@ -159,8 +183,12 @@ class CustomersController extends Controller
}
}
\Eventy::action('customer.updated', $customer);
$flash_message = __('Customer saved successfully.').' '.$flash_message;
\Session::flash('flash_success_unescaped', $flash_message);
\Session::flash('customer.updated', 1);
return redirect()->route('customers.update', ['id' => $id]);
}
@@ -189,7 +217,7 @@ class CustomersController extends Controller
$user = User::findOrFail($id);
$this->authorize('update', $user);
$user->mailboxes()->sync($request->mailboxes);
$user->mailboxes()->sync($request->mailboxes ?: []);
\Session::flash('flash_success', __('Permissions saved successfully'));
@@ -207,12 +235,13 @@ class CustomersController extends Controller
$conversations = $customer->conversations()
->where('customer_id', $customer->id)
->whereIn('mailbox_id', auth()->user()->mailboxesIdsCanView())
->orderBy('created_at', 'desc')
->paginate(Conversation::DEFAULT_LIST_SIZE);
return view('customers/conversations', [
'customer' => $customer,
'conversations' => $conversations
'conversations' => $conversations,
]);
}
@@ -222,33 +251,113 @@ class CustomersController extends Controller
public function ajaxSearch(Request $request)
{
$response = [
'results' => [],
'pagination' => ['more' => false]
'results' => [],
'pagination' => ['more' => false],
];
$q = $request->q;
$customers = Customer::select('customers.id', 'emails.email', 'first_name', 'last_name')
->join('emails', 'customers.id', '=', 'emails.customer_id')
->where('emails.email', 'like', '%'.$q.'%')
->where('emails.email', '<>', $request->exclude_email)
->orWhere('first_name', 'like', '%'.$q.'%')
->orWhere('last_name', 'like', '%'.$q.'%')
->paginate(20);
$user = auth()->user();
$limited_visibility = config('app.limit_user_customer_visibility') && !$user->isAdmin();
$join_emails = false;
if ($request->search_by == 'all' || $request->search_by == 'email' || $request->exclude_email) {
$join_emails = true;
}
$select_list = ['customers.id', 'first_name', 'last_name'];
if ($join_emails) {
$select_list[] = 'emails.email';
}
if ($request->show_fields == 'phone') {
$select_list[] = 'phones';
}
$customers_query = Customer::select($select_list);
if ($join_emails) {
if ($request->allow_non_emails) {
$customers_query->leftJoin('emails', 'customers.id', '=', 'emails.customer_id');
} else {
$customers_query->join('emails', 'customers.id', '=', 'emails.customer_id');
}
}
$customers_query->where(function ($query) use ($q, $request) {
if ($request->search_by == 'all' || $request->search_by == 'email') {
$query->where('emails.email', 'like', '%'.$q.'%');
}
if ($request->exclude_email) {
$query->where('emails.email', '<>', $request->exclude_email);
}
if ($request->search_by == 'all' || $request->search_by == 'name') {
$query->orWhere('first_name', 'like', '%'.$q.'%')
->orWhere('last_name', 'like', '%'.$q.'%');
}
if ($request->search_by == 'phone') {
$phone_numeric = \Helper::phoneToNumeric($q);
if (!$phone_numeric) {
$phone_numeric = $q;
}
$query->where('customers.phones', 'like', '%'.$phone_numeric.'%');
}
});
if ($limited_visibility) {
$mailbox_ids = $user->mailboxesIdsCanView();
$customers_query->join('conversations', 'conversations.customer_id', '=', 'customers.id');
$customers_query->whereIn('conversations.mailbox_id', $mailbox_ids);
$customers_query->groupby('customers.id');
}
$customers = $customers_query->paginate(20);
foreach ($customers as $customer) {
$text = $customer->email;
if ($customer->getFullName()) {
$text .= ' ('.$customer->getFullName().')';
}
if (!empty($request->use_id)) {
$id = $customer->id;
$id = '';
$text = '';
if ($request->show_fields != 'all') {
switch ($request->show_fields) {
case 'email':
$text = $customer->email;
break;
case 'name':
$text = $customer->getFullName();
break;
case 'phone':
// Get phone which matches
$phones = $customer->getPhones();
foreach ($phones as $phone) {
$phone_numeric = \Helper::phoneToNumeric($q);
if (strstr($phone['value'], $q) || strstr($phone['n'] ?? '', $phone_numeric)) {
$text = $phone['value'];
if ($customer->getFullName()) {
$text .= ' — '.$customer->getFullName();
}
$id = $phone['value'];
break;
}
}
break;
default:
$text = $customer->getNameAndEmail();
break;
}
} else {
$id = $customer->email;
$text = $customer->getNameAndEmail();
}
if (!$id) {
if (!empty($request->use_id)) {
$id = $customer->id;
} else {
// https://github.com/freescout-helpdesk/freescout/issues/4057
$id = $customer->email ?? $customer->getMainEmail();
}
}
$response['results'][] = [
'id' => $id,
'text' => $text
'id' => $id,
'text' => $text,
];
}
@@ -256,4 +365,76 @@ class CustomersController extends Controller
return \Response::json($response);
}
}
/**
* Ajax controller.
*/
public function ajax(Request $request)
{
$response = [
'status' => 'error',
'msg' => '', // this is error message
];
$user = auth()->user();
switch ($request->action) {
// Change conversation customer.
case 'create':
$validator_config = [
'first_name' => 'required|string|max:255',
'last_name' => 'nullable|string|max:255',
'email' => 'required|email|unique:emails,email',
];
$limited_visibility = config('app.limit_user_customer_visibility') && !$user->isAdmin();
if ($limited_visibility) {
$validator_config['email'] = 'required|email';
}
// First name or email must be specified.
$validator = Validator::make($request->all(), $validator_config);
if ($validator->fails()) {
foreach ($validator->errors()->getMessages()as $errors) {
foreach ($errors as $field => $message) {
$response['msg'] .= $message.' ';
}
}
}
if (!$response['msg']) {
$customer = Customer::create($request->email, $request->all());
if ($customer) {
$response['email'] = $request->email;
$response['status'] = 'success';
}
}
break;
// Conversations navigation
case 'customers_pagination':
$customers = app('App\Http\Controllers\ConversationsController')->searchCustomers($request, $user);
$response['status'] = 'success';
$response['html'] = view('customers/partials/customers_table', [
'customers' => $customers,
])->render();
break;
default:
$response['msg'] = 'Unknown action';
break;
}
if ($response['status'] == 'error' && empty($response['msg'])) {
$response['msg'] = 'Unknown error occurred';
}
return \Response::json($response);
}
}

696
app/Http/Controllers/MailboxesController.php Normal file → Executable file
View File

@@ -5,6 +5,7 @@ namespace App\Http\Controllers;
use App\Conversation;
use App\Folder;
use App\Mailbox;
use App\MailboxUser;
use App\Thread;
use App\User;
use Illuminate\Http\Request;
@@ -29,9 +30,17 @@ class MailboxesController extends Controller
*/
public function mailboxes()
{
//$this->authorize('create', 'App\Mailbox');
//$mailboxes = Mailbox::all();
$mailboxes = auth()->user()->mailboxesCanView();
$user = auth()->user();
$mailboxes = $user->mailboxesCanView();
if (!\Eventy::filter('user.can_view_mailbox_menu', false, $user)) {
foreach ($mailboxes as $i => $mailbox) {
if (!$user->canManageMailbox($mailbox->id)) {
$mailboxes->forget($i);
}
}
}
return view('mailboxes/mailboxes', ['mailboxes' => $mailboxes]);
}
@@ -43,7 +52,7 @@ class MailboxesController extends Controller
{
$this->authorize('create', 'App\Mailbox');
$users = User::where('role', '!=', User::ROLE_ADMIN)->get();
$users = User::nonDeleted()->where('role', '!=', User::ROLE_ADMIN)->get();
return view('mailboxes/create', ['users' => $users]);
}
@@ -55,6 +64,8 @@ class MailboxesController extends Controller
*/
public function createSave(Request $request)
{
$invalid = false;
$this->authorize('create', 'App\Mailbox');
$validator = Validator::make($request->all(), [
@@ -64,7 +75,12 @@ class MailboxesController extends Controller
// //event(new Registered($user = $this->create($request->all())));
if ($validator->fails()) {
if (Mailbox::userEmailExists($request->email)) {
$invalid = true;
$validator->errors()->add('email', __('There is a user with such email. Users and mailboxes can not have the same email addresses.'));
}
if ($invalid || $validator->fails()) {
return redirect()->route('mailboxes.create')
->withErrors($validator)
->withInput();
@@ -72,9 +88,10 @@ class MailboxesController extends Controller
$mailbox = new Mailbox();
$mailbox->fill($request->all());
$mailbox->save();
$mailbox->users()->sync($request->users);
$mailbox->users()->sync($request->users ?: []);
$mailbox->syncPersonalFolders($request->users);
\Session::flash('flash_success_floating', __('Mailbox created successfully'));
@@ -88,9 +105,29 @@ class MailboxesController extends Controller
public function update($id)
{
$mailbox = Mailbox::findOrFail($id);
//$this->authorize('update', $mailbox);
if (!auth()->user()->can('update', $mailbox)) {
$accessible_route = \Eventy::filter('mailbox.accessible_settings_route', '', auth()->user(), $mailbox);
$user = auth()->user();
if (!$user->can('updateSettings', $mailbox) && !$user->can('updateEmailSignature', $mailbox)) {
$accessible_route = '';
$mailbox_settings = $user->mailboxSettings($mailbox->id);
if (!is_array($mailbox_settings->access)) {
$access_permissions = json_decode($mailbox_settings->access ?? '');
} else {
$access_permissions = $mailbox_settings->access;
}
if ($access_permissions && is_array($access_permissions)) {
foreach ($access_permissions as $perm) {
$accessible_route = Mailbox::getAccessPermissionRoute($perm);
if ($accessible_route) {
break;
}
}
}
if (!$accessible_route) {
$accessible_route = \Eventy::filter('mailbox.accessible_settings_route', '', auth()->user(), $mailbox);
}
if ($accessible_route) {
return redirect()->route($accessible_route, ['id' => $mailbox->id]);
} else {
@@ -98,9 +135,17 @@ class MailboxesController extends Controller
}
}
$user = auth()->user();
$mailbox_user = $user->mailboxesWithSettings()->where('mailbox_id', $id)->first();
if (!$mailbox_user && $user->isAdmin()) {
// Admin may not be connected to the mailbox yet
$user->mailboxes()->attach($id);
$mailbox_user = $user->mailboxesWithSettings()->where('mailbox_id', $id)->first();
}
//$mailboxes = Mailbox::all()->except($id);
return view('mailboxes/update', ['mailbox' => $mailbox, 'flashes' => $this->mailboxActiveWarning($mailbox)]);
return view('mailboxes/update', ['mailbox' => $mailbox, 'mailbox_user' => $mailbox_user, 'flashes' => $this->mailboxActiveWarning($mailbox)]);
}
/**
@@ -111,31 +156,72 @@ class MailboxesController extends Controller
*/
public function updateSave($id, Request $request)
{
$invalid = false;
$mailbox = Mailbox::findOrFail($id);
$this->authorize('update', $mailbox);
$validator = Validator::make($request->all(), [
'name' => 'required|string|max:40',
'email' => 'required|string|email|max:128|unique:mailboxes,email,'.$id,
'aliases' => 'nullable|string|max:255',
'from_name' => 'required|integer',
'from_name_custom' => 'nullable|string|max:128',
'ticket_status' => 'required|integer',
'template' => 'required|integer',
'ticket_assignee' => 'required|integer',
'signature' => 'nullable|string',
]);
//event(new Registered($user = $this->create($request->all())));
if ($validator->fails()) {
return redirect()->route('mailboxes.update', ['id' => $id])
->withErrors($validator)
->withInput();
$user = auth()->user();
if (!$user->can('updateSettings', $mailbox) && !$user->can('updateEmailSignature', $mailbox)) {
\Helper::denyAccess();
}
if ($user->can('updateSettings', $mailbox)) {
// Checkboxes
$request->merge([
'aliases_reply' => ($request->filled('aliases_reply') ?? false),
]);
// if not admin, the text only fields don't pass so spike them into the request.
if (!auth()->user()->isAdmin()) {
$request->merge([
'name' => $mailbox->name,
'email' => $mailbox->email
]);
}
$validator = Validator::make($request->all(), [
'name' => 'required|string|max:40',
'email' => 'required|string|email|max:128|unique:mailboxes,email,'.$id,
'aliases' => 'nullable|string',
'from_name' => 'required|integer',
'from_name_custom' => 'nullable|string|max:128',
'ticket_status' => 'required|integer',
'template' => 'required|integer',
'ticket_assignee' => 'required|integer',
]);
//event(new Registered($user = $this->create($request->all())));
if (Mailbox::userEmailExists($request->email)) {
$invalid = true;
$validator->errors()->add('email', __('There is a user with such email. Users and mailboxes can not have the same email addresses.'));
}
$validator = \Eventy::filter('mailbox.settings_validator', $validator, $mailbox, $request);
if ($invalid || count($validator->errors()) || $validator->fails()) {
return redirect()->route('mailboxes.update', ['id' => $id])
->withErrors($validator)
->withInput();
}
}
if ($user->can('updateEmailSignature', $mailbox)) {
$validator = Validator::make($request->all(), [
'signature' => 'nullable|string',
]);
if ($validator->fails()) {
return redirect()->route('mailboxes.email_signature', ['id' => $id])
->withErrors($validator)
->withInput();
}
}
\Eventy::action('mailbox.settings_before_save', $mailbox, $request);
$mailbox->fill($request->all());
$mailbox->signature = \Helper::stripDangerousTags($mailbox->signature);
$mailbox->save();
@@ -151,11 +237,25 @@ class MailboxesController extends Controller
{
$mailbox = Mailbox::findOrFail($id);
$this->authorize('update', $mailbox);
$this->authorize('updatePermissions', $mailbox);
$users = User::where('role', '!=', User::ROLE_ADMIN)->get();
$users = User::nonDeleted()->where('role', '!=', User::ROLE_ADMIN)->get();
$users = User::sortUsers($users);
return view('mailboxes/permissions', ['mailbox' => $mailbox, 'users' => $users, 'mailbox_users' => $mailbox->users]);
$managers = User::nonDeleted()
->select(['users.*', 'mailbox_user.hide', 'mailbox_user.access'])
->leftJoin('mailbox_user', function ($join) use ($mailbox) {
$join->on('mailbox_user.user_id', '=', 'users.id');
$join->where('mailbox_user.mailbox_id', $mailbox->id);
})->get();
$managers = User::sortUsers($managers);
return view('mailboxes/permissions', [
'mailbox' => $mailbox,
'users' => $users,
'managers' => $managers,
'mailbox_users' => $mailbox->users,
]);
}
/**
@@ -167,11 +267,72 @@ class MailboxesController extends Controller
public function permissionsSave($id, Request $request)
{
$mailbox = Mailbox::findOrFail($id);
$this->authorize('update', $mailbox);
$this->authorize('updatePermissions', $mailbox);
$user = auth()->user();
$user_ids = \Eventy::filter('mailbox.permission_users', $request->users ?? [], $id);
// Get pivot data from mailbox_user to pass to sync() not to loose values.
// https://github.com/freescout-help-desk/freescout/issues/4339
$users_with_settings = [];
$mailbox_users = MailboxUser::where('mailbox_id', $id)
//->whereIn('user_id', $user_ids)
->get()
->keyBy('user_id')
->toArray();
foreach ($user_ids as $user_id) {
$users_with_settings[$user_id] = $mailbox_users[$user_id] ?? [];
}
// Settings for admins are being reset here.
// So we restore them below.
$mailbox->users()->sync($users_with_settings);
$mailbox->users()->sync($request->users);
$mailbox->syncPersonalFolders($request->users);
// Save admins settings.
$admins = User::nonDeleted()->where('role', User::ROLE_ADMIN)->get();
foreach ($admins as $admin) {
$mailbox_user = $admin->mailboxesWithSettings()->where('mailbox_id', $id)->first();
if (!$mailbox_user) {
// Admin may not be connected to the mailbox yet
$admin->mailboxes()->attach($id);
$mailbox_user = $admin->mailboxesWithSettings()->where('mailbox_id', $id)->first();
}
// Restore settings for admins.
if (!empty($mailbox_users[$admin->id])) {
$admin_settings = $mailbox_users[$admin->id];
foreach (MailboxUser::$pivot_settings as $pivot_parameter) {
if (isset($admin_settings[$pivot_parameter])) {
$mailbox_user->settings->$pivot_parameter = $admin_settings[$pivot_parameter];
}
}
}
$mailbox_user->settings->hide = (isset($request->managers[$admin->id]['hide']) ? (int)$request->managers[$admin->id]['hide'] : false);
$mailbox_user->settings->save();
}
// Sets the mailbox_user.access array
$mailbox_users = $mailbox->users;
foreach ($mailbox_users as $mailbox_user) {
$access = [];
$mailbox_with_settings = $mailbox_user->mailboxesWithSettings()->where('mailbox_id', $id)->first();
foreach (Mailbox::$access_permissions as $perm) {
if (!empty($request->managers[$mailbox_user->id]['access'][$perm])) {
$access[] = $request->managers[$mailbox_user->id]['access'][$perm];
}
}
if ($user->id == $mailbox_user->id && !$user->isAdmin()) {
// User with Permission priv's can't edit their own additional priv's.
} else {
$mailbox_with_settings->settings->access = json_encode($access);
}
$mailbox_with_settings->settings->hide = (isset($request->managers[$mailbox_user->id]['hide']) ? (int)$request->managers[$mailbox_user->id]['hide'] : false);
$mailbox_with_settings->settings->save();
}
\Session::flash('flash_success_floating', __('Mailbox permissions saved!'));
return redirect()->route('mailboxes.permissions', ['id' => $id]);
@@ -183,7 +344,7 @@ class MailboxesController extends Controller
public function connectionOutgoing($id)
{
$mailbox = Mailbox::findOrFail($id);
$this->authorize('update', $mailbox);
$this->authorize('admin', $mailbox);
return view('mailboxes/connection', ['mailbox' => $mailbox, 'sendmail_path' => ini_get('sendmail_path'), 'flashes' => $this->mailboxActiveWarning($mailbox)]);
}
@@ -194,14 +355,14 @@ class MailboxesController extends Controller
public function connectionOutgoingSave($id, Request $request)
{
$mailbox = Mailbox::findOrFail($id);
$this->authorize('update', $mailbox);
$this->authorize('admin', $mailbox);
if ($request->out_method == Mailbox::OUT_METHOD_SMTP) {
$validator = Validator::make($request->all(), [
'out_server' => 'required|string|max:255',
'out_port' => 'required|integer',
'out_username' => 'required|string|max:100',
'out_password' => 'required|string|max:255',
'out_username' => 'nullable|string|max:100',
'out_password' => 'nullable|string|max:255',
'out_encryption' => 'required|integer',
]);
@@ -212,9 +373,22 @@ class MailboxesController extends Controller
}
}
$mailbox->fill($request->all());
// Do not save dummy password.
if (preg_match("/^\*+$/", $request->out_password ?? '')) {
$params = $request->except(['out_password']);
} else {
$params = $request->all();
}
$mailbox->fill($params);
$mailbox->save();
if (!empty($request->send_test_to)) {
\Option::set('send_test_to', $request->send_test_to);
}
// Sometimes background job continues to use old connection settings.
\Helper::queueWorkerRestart();
\Session::flash('flash_success_floating', __('Connection settings saved!'));
return redirect()->route('mailboxes.connection', ['id' => $id]);
@@ -223,12 +397,26 @@ class MailboxesController extends Controller
/**
* Mailbox incoming settings.
*/
public function connectionIncoming($id)
public function connectionIncoming($id, Request $request)
{
$mailbox = Mailbox::findOrFail($id);
$this->authorize('update', $mailbox);
$this->authorize('admin', $mailbox);
return view('mailboxes/connection_incoming', ['mailbox' => $mailbox, 'flashes' => $this->mailboxActiveWarning($mailbox)]);
$fields = [
'in_server' => $mailbox->in_server ?? '',
'in_port' => $mailbox->in_port ?? '',
'in_username' => $mailbox->in_username ?? '',
'in_password' => $mailbox->in_password ?? '',
];
$validator = Validator::make($fields, [
'in_server' => 'required',
'in_port' => 'required',
'in_username' => 'required',
'in_password' => 'required',
]);
return view('mailboxes/connection_incoming', ['mailbox' => $mailbox, 'flashes' => $this->mailboxActiveWarning($mailbox)])->withErrors($validator);
}
/**
@@ -237,22 +425,47 @@ class MailboxesController extends Controller
public function connectionIncomingSave($id, Request $request)
{
$mailbox = Mailbox::findOrFail($id);
$this->authorize('update', $mailbox);
$this->authorize('admin', $mailbox);
$validator = Validator::make($request->all(), [
'in_server' => 'required|string|max:255',
'in_port' => 'required|integer',
'in_username' => 'required|string|max:100',
'in_password' => 'required|string|max:255',
// $validator = Validator::make($request->all(), [
// 'in_server' => 'nullable|string|max:255',
// 'in_port' => 'nullable|integer',
// 'in_username' => 'nullable|string|max:100',
// 'in_password' => 'nullable|string|max:255',
// ]);
// if ($validator->fails()) {
// return redirect()->route('mailboxes.connection.incoming', ['id' => $id])
// ->withErrors($validator)
// ->withInput();
// }
// Checkboxes
$request->merge([
'in_validate_cert' => ($request->filled('in_validate_cert') ?? false),
]);
if ($validator->fails()) {
return redirect()->route('mailboxes.connection.incoming', ['id' => $id])
->withErrors($validator)
->withInput();
// Do not save dummy password.
if (preg_match("/^\*+$/", $request->in_password ?? '')) {
$params = $request->except(['in_password']);
} else {
$params = $request->all();
}
$mailbox->fill($request->all());
\Eventy::action('mailbox.incoming_settings_before_save', $mailbox, $request);
$mailbox->fill($params);
// Save IMAP Folders.
// Save all custom folders except INBOX.
$in_imap_folders = [];
if (is_array($request->in_imap_folders)) {
foreach ($request->in_imap_folders as $imap_folder) {
$in_imap_folders[] = $imap_folder;
}
}
$mailbox->setInImapFolders($in_imap_folders);
$mailbox->save();
\Session::flash('flash_success_floating', __('Connection settings saved!'));
@@ -263,12 +476,12 @@ class MailboxesController extends Controller
/**
* View mailbox.
*/
public function view($id, $folder_id = null)
public function view(Request $request, $id, $folder_id = null)
{
//auth()->guard()->attempt(['email' => '', 'password' => '']);
$user = auth()->user();
$mailbox = Mailbox::findOrFail($id);
$this->authorize('view', $mailbox);
$mailbox = Mailbox::findOrFailWithSettings($id, $user->id);
$this->authorize('viewCached', $mailbox);
$folders = $mailbox->getAssesibleFolders();
@@ -287,10 +500,10 @@ class MailboxesController extends Controller
$this->authorize('view', $folder);
$user = auth()->user();
$query_conversations = Conversation::getQueryByFolder($folder, $user->id);
$conversations = $folder->queryAddOrderBy($query_conversations)->paginate(Conversation::DEFAULT_LIST_SIZE);
$conversations = $folder->queryAddOrderBy($query_conversations)->paginate(
Conversation::DEFAULT_LIST_SIZE, ['*'], 'page', $request->get('page')
);
return view('mailboxes/view', [
'mailbox' => $mailbox,
@@ -304,7 +517,7 @@ class MailboxesController extends Controller
{
$flashes = [];
if ($mailbox) {
if ($mailbox && \Auth::user()->can('admin', $mailbox)) {
if (Route::currentRouteName() != 'mailboxes.connection' && !$mailbox->isOutActive()) {
$flashes[] = [
'type' => 'warning',
@@ -330,14 +543,14 @@ class MailboxesController extends Controller
public function autoReply($id)
{
$mailbox = Mailbox::findOrFail($id);
$this->authorize('update', $mailbox);
$this->authorize('updateAutoReply', $mailbox);
if (!$mailbox->auto_reply_subject) {
$mailbox->auto_reply_subject = 'Re: {%subject%}';
}
return view('mailboxes/auto_reply', [
'mailbox' => $mailbox
'mailbox' => $mailbox,
]);
}
@@ -348,10 +561,11 @@ class MailboxesController extends Controller
{
$mailbox = Mailbox::findOrFail($id);
$this->authorize('update', $mailbox);
// $this->authorize('update', $mailbox);
$this->authorize('updateAutoReply', $mailbox);
$request->merge([
'auto_reply_enabled' => ($request->filled('auto_reply_enabled') ?? false)
'auto_reply_enabled' => ($request->filled('auto_reply_enabled') ?? false),
]);
if ($request->auto_reply_enabled) {
@@ -363,8 +577,8 @@ class MailboxesController extends Controller
]);
$validator->setAttributeNames([
'auto_reply_subject' => __('Subject'),
'auto_reply_message' => __('Message')
]);
'auto_reply_message' => __('Message'),
]);
if ($validator->fails()) {
return redirect()->route('mailboxes.auto_reply', ['id' => $id])
@@ -374,6 +588,7 @@ class MailboxesController extends Controller
}
$mailbox->fill($request->all());
$mailbox->auto_reply_message = \Helper::stripDangerousTags($mailbox->auto_reply_message);
$mailbox->save();
@@ -382,6 +597,24 @@ class MailboxesController extends Controller
return redirect()->route('mailboxes.auto_reply', ['id' => $id]);
}
/**
* Auto reply settings.
*/
public function emailSignature($id)
{
$mailbox = Mailbox::findOrFail($id);
$this->authorize('updateAutoReply', $mailbox);
if (!$mailbox->auto_reply_subject) {
$mailbox->auto_reply_subject = 'Re: {%subject%}';
}
return view('mailboxes/email_signature', [
'mailbox' => $mailbox,
]);
}
/**
* Users ajax controller.
*/
@@ -402,24 +635,37 @@ class MailboxesController extends Controller
if (!$mailbox) {
$response['msg'] = __('Mailbox not found');
} elseif (!$user->can('update', $mailbox)) {
} elseif (!$user->can('admin', $mailbox)) {
$response['msg'] = __('Not enough permissions');
} elseif (empty($request->to)) {
$response['msg'] = __('Please specify recipient of the test email');
}
// Check if outgoing port is open.
if (!$response['msg'] && $mailbox->out_method == Mailbox::OUT_METHOD_SMTP) {
$test_result = \Helper::checkPort($mailbox->out_server, $mailbox->out_port);
if (!$test_result) {
$response['msg'] = __(':host is not available on :port port. Make sure that :host address is correct and that outgoing port :port on YOUR server is open.', ['host' => '<strong>'.$mailbox->out_server.'</strong>', 'port' => '<strong>'.$mailbox->out_port.'</strong>']);
}
}
if (!$response['msg']) {
$test_result = false;
$test_result = [
'status' => 'error'
];
try {
$test_result = \App\Misc\Mail::sendTestMail($request->to, $mailbox);
$test_result = \MailHelper::sendTestMail($request->to, $mailbox);
} catch (\Exception $e) {
$response['msg'] = $e->getMessage();
$test_result['msg'] = $e->getMessage();
}
if (!$test_result && !$response['msg']) {
$response['msg'] = __('Error occurend sending email. Please check your mail server logs for more details.');
if ($test_result['status'] == 'error') {
$response['msg'] = $test_result['msg']
?: __('Error occurred sending email. Please check your mail server logs for more details.');
}
$response['log'] = $test_result['log'] ?? '';
}
if (!$response['msg']) {
@@ -437,23 +683,98 @@ class MailboxesController extends Controller
$mailbox = Mailbox::find($request->mailbox_id);
if (!$mailbox) {
$response['msg'] = __('Conversation not found');
} elseif (!$user->can('update', $mailbox)) {
$response['msg'] = __('Mailbox not found');
} elseif (!$user->can('admin', $mailbox)) {
$response['msg'] = __('Not enough permissions');
}
if (!$response['msg']) {
$response = \Eventy::filter('mailbox.fetch_test', $response, $mailbox);
$tested = (isset($response['tested']) && $response['tested'] === true);
// Check if outgoing port is open.
if (!$response['msg'] && !$tested) {
$test_result = \Helper::checkPort($mailbox->in_server, $mailbox->in_port);
if (!$test_result) {
$response['msg'] = __(':host is not available on :port port. Make sure that :host address is correct and that outgoing port :port on YOUR server is open.', ['host' => '<strong>'.$mailbox->in_server.'</strong>', 'port' => '<strong>'.$mailbox->in_port.'</strong>']);
}
}
if (!$response['msg'] && !$tested) {
$test_result = false;
$test_result = \MailHelper::fetchTest($mailbox);
$response['log'] = $test_result['log'] ?? '';
if ($test_result['result'] != 'success' && $test_result['msg']) {
$response['msg'] = $test_result['msg'];
}
if ($test_result['result'] != 'success' && !$response['msg']) {
$response['msg'] = __('Error occurred connecting to the server');
}
}
if (!$response['msg'] && !$tested) {
$response['status'] = 'success';
}
break;
// Retrieve a list of available IMAP folders from server.
case 'imap_folders':
$mailbox = Mailbox::find($request->mailbox_id);
if (!$mailbox) {
$response['msg'] = __('Mailbox not found');
} elseif (!$user->can('admin', $mailbox)) {
$response['msg'] = __('Not enough permissions');
}
$response['folders'] = [];
if (!$response['msg']) {
try {
$test_result = \App\Misc\Mail::fetchTest($mailbox);
$client = \MailHelper::getMailboxClient($mailbox);
$client->connect();
$imap_folders = $client->getFolders();
$response['folders'] = [];
if (count($imap_folders)) {
$response = $this->interateFolders($response, $imap_folders);
$response['folders'] = array_values(array_unique($response['folders']));
}
if (count($response['folders'])) {
// https://github.com/freescout-helpdesk/freescout/issues/3933
// Exclude duplicate INBOX.Name and Name folders.
// $folder_excluded = false;
// foreach ($response['folders'] as $i => $folder_name) {
// if (\Str::startsWith($folder_name, 'INBOX.')) {
// foreach ($response['folders'] as $folder_name2) {
// if ($folder_name != $folder_name2 && $folder_name == 'INBOX.'.$folder_name2) {
// unset($response['folders'][$i]);
// $folder_excluded = true;
// continue 2;
// }
// }
// }
// }
// if ($folder_excluded) {
// $response['folders'] = array_values($response['folders']);
// }
$response['msg_success'] = __('IMAP folders retrieved: '.implode(', ', $response['folders']));
} else {
$response['msg_success'] = __('Connected, but no IMAP folders found');
}
} catch (\Exception $e) {
$response['msg'] = $e->getMessage();
}
if (!$test_result && !$response['msg']) {
$response['msg'] = __('Error occurend connecting to the server');
}
}
if (!$response['msg']) {
@@ -467,22 +788,27 @@ class MailboxesController extends Controller
if (!$mailbox) {
$response['msg'] = __('Mailbox not found');
} elseif (!$user->can('update', $mailbox)) {
} elseif (!$user->can('admin', $mailbox)) {
$response['msg'] = __('Not enough permissions');
} elseif (!Hash::check($request->password, $user->password)) {
} elseif (!$user->isDummyPassword() && !Hash::check($request->password ?? '', $user->password)) {
$response['msg'] = __('Please double check your password, and try again');
}
if (!$response['msg']) {
// Remove threads and conversations
Thread::whereIn('conversation_id', $mailbox->conversations()->pluck('id')->toArray())
->delete();
// Remove threads and conversations.
$conversation_ids = $mailbox->conversations()->pluck('id')->toArray();
for ($i=0; $i < ceil(count($conversation_ids) / \Helper::IN_LIMIT); $i++) {
$slice_ids = array_slice($conversation_ids, $i*\Helper::IN_LIMIT, \Helper::IN_LIMIT);
Thread::whereIn('conversation_id', $slice_ids)->delete();
}
$mailbox->conversations()->delete();
$mailbox->users()->sync([]);
$mailbox->folders()->delete();
// Maybe remove notifications on events in this mailbox?
$mailbox->delete();
\Session::flash('flash_success_floating', __('Mailbox deleted'));
@@ -491,15 +817,205 @@ class MailboxesController extends Controller
}
break;
// Mute notifications
case 'mute':
$mailbox = Mailbox::find($request->mailbox_id);
if (!$mailbox) {
$response['msg'] = __('Mailbox not found');
}
if (!$response['msg']) {
$mailbox_user = $user->mailboxesWithSettings()->where('mailbox_id', $mailbox->id)->first();
if (!$mailbox_user) {
// User may not be connected to the mailbox yet
$user->mailboxes()->attach($mailbox->id);
$mailbox_user = $user->mailboxesWithSettings()->where('mailbox_id', $mailbox->id)->first();
}
$mailbox_user->settings->mute = (bool)$request->mute;
$mailbox_user->settings->save();
$response['status'] = 'success';
}
break;
default:
$response['msg'] = 'Unknown action';
break;
}
if ($response['status'] == 'error' && empty($response['msg'])) {
$response['msg'] = 'Unknown error occured';
$response['msg'] = 'Unknown error occurred';
}
return \Response::json($response);
}
// Recursively interate over folders.
public function interateFolders($response, $imap_folders, $subfolder = false) {
foreach ($imap_folders as $imap_folder) {
if (!empty($imap_folder->name) && !$subfolder) {
$response['folders'][] = $imap_folder->name;
}
// Check for children and recurse.
if (!empty($imap_folder->children)) {
$response = $this->interateFolders($response, $imap_folder->children, true);
}
// Old library.
if (!empty($imap_folder->fullName)) {
$response['folders'][] = $imap_folder->fullName;
} elseif (!empty($imap_folder->full_name)) {
// New library.
$response['folders'][] = $imap_folder->full_name;
}
}
return $response;
}
public function oauth(Request $request)
{
$mailbox_id = $request->id ?? '';
$provider = $request->provider ?? '';
$in_out = $request->in_out ?? 'in';
$state_data = [];
if (!empty($request->state)) {
$state_data = json_decode($request->state, true);
if (!empty($state_data['mailbox_id'])) {
$mailbox_id = $state_data['mailbox_id'];
}
if (!empty($state_data['provider'])) {
$provider = $state_data['provider'];
}
if (!empty($state_data['in_out'])) {
$in_out = $state_data['in_out'];
}
}
// MS Exchange.
if (!empty($request->error) && $request->error == 'invalid_request' && !empty($request->error_description)) {
return htmlspecialchars($request->error_description);
}
if (empty($provider)) {
return 'Invalid oAuth Provider';
}
$mailbox = Mailbox::findOrFail($mailbox_id);
$this->authorize('admin', $mailbox);
if (empty($mailbox)) {
return __('Mailbox not found').': '.$mailbox_id;
}
if ($in_out == 'in') {
$username = $mailbox->in_username;
$password = $mailbox->in_password;
} else {
$username = $mailbox->out_username;
$password = $mailbox->out_password;
}
if (empty($username)) {
return 'Enter oAuth Client ID as Username and save mailbox settings';
}
if (empty($password)) {
return 'Enter oAuth Client Secret as Password and save mailbox settings';
}
$session_data = [];
if (\Session::get('mailbox_oauth_'.$provider.'_'.$mailbox_id)) {
$session_data = \Session::get('mailbox_oauth_'.$provider.'_'.$mailbox_id);
}
if (empty($request->code)) {
// Start.
$state = [
'provider' => $provider,
'mailbox_id' => $mailbox_id,
'in_out' => $in_out,
'state' => crc32($username.$password),
];
$url = \MailHelper::oauthGetAuthorizationUrl(\MailHelper::OAUTH_PROVIDER_MICROSOFT, [
'state' => json_encode($state),
'client_id' => $username,
]);
if ($url) {
\Session::put('mailbox_oauth_'.$provider.'_'.$mailbox_id, $state);
// [
// 'provider' => $request->provider,
// 'mailbox_id' => $request->mailbox_id,
// 'state' => $provider->getState(),
// ]);
return redirect()->away($url);
} else {
return 'Could not generate authorization URL: check Client ID (Username) and Client Secret (Password)';
}
// Check given state against previously stored one to mitigate CSRF attack
} elseif (empty($request->state) || ($state_data['state'] ?? '') !== ($session_data['state'] ?? '')) {
\Session::forget('mailbox_oauth_'.$provider.'_'.$mailbox_id);
return 'Invalid oAuth state';
} else {
// state is set.
// Try to get an access token (using the authorization code grant)
$token_data = \MailHelper::oauthGetAccessToken(\MailHelper::OAUTH_PROVIDER_MICROSOFT, [
'client_id' => $username,
'client_secret' => $password,
'code' => $request->code,
]);
if (!empty($token_data['a_token'])) {
// Set username and password for the oppozite in_out.
if ($in_out == 'in') {
if (empty($mailbox->out_server)
|| (trim($mailbox->out_server) == \MailHelper::OAUTH_MICROSOFT_SMTP
&& (!$mailbox->out_username || $mailbox->out_username == $username))
) {
$mailbox->out_username = $username;
$mailbox->out_password = $password;
}
//$mailbox->out_method = Mailbox::OUT_METHOD_SMTP;
} else {
$mailbox->in_username = $username;
$mailbox->in_password = $password;
}
$mailbox->setMetaParam('oauth', $token_data, true);
} elseif (!empty($token_data['error'])) {
return __('Error occurred').': '.htmlspecialchars($token_data['error']);
}
if ($in_out == 'in') {
$route = 'mailboxes.connection.incoming';
} else {
$route = 'mailboxes.connection';
}
return redirect()->route($route, ['id' => $mailbox_id]);
}
}
public function oauthDisconnect(Request $request)
{
$mailbox_id = $request->id ?? '';
$provider = $request->provider ?? '';
$in_out = $request->in_out ?? 'in';
$mailbox = Mailbox::findOrFail($mailbox_id);
$this->authorize('admin', $mailbox);
// oAuth Disconnect.
$mailbox->removeMetaParam('oauth', true);
if ($in_out == 'in') {
$route = 'mailboxes.connection.incoming';
} else {
$route = 'mailboxes.connection';
}
return \MailHelper::oauthDisconnect($provider, route($route, ['id' => $mailbox_id]));
}
}

View File

@@ -28,11 +28,18 @@ class ModulesController extends Controller
{
$installed_modules = [];
$modules_directory = [];
$third_party_modules = [];
$all_modules = [];
$flashes = [];
$updates_available = false;
$flash = \Cache::get('modules_flash');
if ($flash) {
$flashes[] = $flash;
if (is_array($flash) && !isset($flash['text'])) {
$flashes = $flash;
} else {
$flashes[] = $flash;
}
\Cache::forget('modules_flash');
}
@@ -52,22 +59,31 @@ class ModulesController extends Controller
\Module::clearCache();
$modules = \Module::all();
foreach ($modules as $module) {
$img = '';
$installed_modules[] = [
'alias' => $module->getAlias(),
'name' => $module->getName(),
'description' => $module->getDescription(),
'version' => $module->get('version'),
'detailsUrl' => $module->get('detailsUrl'),
'author' => $module->get('author'),
'authorUrl' => $module->get('authorUrl'),
'requiredAppVersion' => $module->get('requiredAppVersion'),
'img' => $img,
'active' => $module->active(), //\App\Module::isActive($module->getAlias()),
'installed' => true,
'activated' => \App\Module::isLicenseActivated($module->getAlias(), $module->get('authorUrl')),
'license' => \App\Module::getLicense($module->getAlias()),
$module_data = [
'alias' => $module->getAlias(),
'name' => $module->getName(),
'description' => $module->getDescription(),
'version' => $module->get('version'),
'detailsUrl' => $module->get('detailsUrl'),
'author' => $module->get('author'),
'authorUrl' => $module->get('authorUrl'),
'requiredAppVersion' => $module->get('requiredAppVersion'),
'requiredPhpExtensions' => $module->get('requiredPhpExtensions'),
'requiredPhpExtensionsMissing' => \App\Module::getMissingExtensions($module->get('requiredPhpExtensions')),
'requiredModulesMissing' => \App\Module::getMissingModules($module->get('requiredModules'), $modules),
'img' => $module->get('img'),
'active' => $module->active(), //\App\Module::isActive($module->getAlias()),
'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' => '',
];
$module_data = \App\Module::formatModuleData($module_data);
$installed_modules[] = $module_data;
}
// No need, as we update modules list on each page load
@@ -79,12 +95,27 @@ class ModulesController extends Controller
// Prepare directory modules
if (is_array($modules_directory)) {
foreach ($modules_directory as $i_dir => $dir_module) {
// Remove installed modules from modules directory
$modules_directory[$i_dir] = \App\Module::formatModuleData($dir_module);
// Remove modules without aliases
if (empty($dir_module['alias'])) {
unset($modules_directory[$i_dir]);
}
$all_modules[$dir_module['alias']] = $dir_module['name'];
foreach ($installed_modules as $i_installed => $module) {
if ($dir_module['alias'] == $module['alias']) {
// Set image from director
$installed_modules[$i_installed]['img'] = $dir_module['img'];
// Remove installed modules from modules directory.
unset($modules_directory[$i_dir]);
// Detect if new version is available
if (!empty($dir_module['version']) && version_compare($dir_module['version'], $module['version'], '>')) {
$installed_modules[$i_installed]['new_version'] = $dir_module['version'];
$updates_available = true;
}
continue 2;
}
}
@@ -94,17 +125,81 @@ class ModulesController extends Controller
continue;
}
if (!empty($dir_module['requiredPhpExtensions'])) {
$modules_directory[$i_dir]['requiredPhpExtensionsMissing'] = \App\Module::getMissingExtensions($dir_module['requiredPhpExtensions']);
}
$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 Directory.
if (\App\Module::isThirdParty($dir_module)) {
$third_party_modules[] = $modules_directory[$i_dir];
unset($modules_directory[$i_dir]);
}
}
} else {
$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()
);
// Sort all modules.
asort($all_modules);
return view('modules/modules', [
'installed_modules' => $installed_modules,
'modules_directory' => $modules_directory,
'flashes' => $flashes
'third_party_modules' => $third_party_modules,
'flashes' => $flashes,
'updates_available' => $updates_available,
'all_modules' => $all_modules,
'invalid_symlinks' => $invalid_symlinks,
]);
}
@@ -123,7 +218,7 @@ class ModulesController extends Controller
case 'install':
case 'activate_license':
$license = $request->license;
$alias = $request->alias;
$alias = $request->alias;
if (!$license) {
$response['msg'] = __('Empty license key');
@@ -133,31 +228,31 @@ class ModulesController extends Controller
$params = [
'license' => $license,
'module_alias' => $alias,
'url' => $request->getHttpHost(),
'url' => \App\Module::getAppUrl(),
];
$result = WpApi::activateLicense($params);
if (WpApi::$lastError) {
$response['msg'] = WpApi::$lastError['message'];
} else if (!empty($result['code']) && !empty($result['message'])) {
} elseif (!empty($result['code']) && !empty($result['message'])) {
$response['msg'] = $result['message'];
} else {
if (!empty($result['status']) && $result['status'] == 'valid') {
if ($request->action == 'install') {
// Download and install module
$license_details = WpApi::getVersion($params);
if (WpApi::$lastError) {
$response['msg'] = WpApi::$lastError['message'];
} else if (!empty($license_details['code']) && !empty($license_details['message'])) {
} elseif (!empty($license_details['code']) && !empty($license_details['message'])) {
$response['msg'] = $license_details['message'];
} elseif (!empty($license_details['download_link'])) {
// Download module
$module_archive = \Module::getPath().DIRECTORY_SEPARATOR.$alias.'.zip';
try {
\Helper::downloadRemoteFile($license_details['download_link'], $module_archive);
} catch(\Exception $e) {
} catch (\Exception $e) {
$response['msg'] = $e->getMessage();
}
@@ -168,7 +263,7 @@ class ModulesController extends Controller
// Extract
try {
\Helper::unzip($module_archive, \Module::getPath());
} catch(\Exception $e) {
} catch (\Exception $e) {
$response['msg'] = $e->getMessage();
}
// Check if extracted module exists
@@ -190,19 +285,17 @@ class ModulesController extends Controller
\Session::flash('flash_success_floating', __('Module successfully installed!'));
$response['status'] = 'success';
} elseif ($download_error) {
$response['reload'] = true;
if ($response['msg']) {
\Session::flash('flash_error_floating', $response['msg']);
}
\Session::flash('flash_error_unescaped', __('Error occured downloading the module. Please :%a_being%download:%a_end% module manually and extract into :folder', ['%a_being%' => '<a href="'.$license_details['download_link'].'" target="_blank">', '%a_end%' => '</a>', 'folder' => '<strong>'.\Module::getPath().'</strong>']));
\Session::flash('flash_error_unescaped', __('Error occurred downloading the module. Please :%a_being%download:%a_end% module manually and extract into :folder', ['%a_being%' => '<a href="'.$license_details['download_link'].'" target="_blank">', '%a_end%' => '</a>', 'folder' => '<strong>'.\Module::getPath().'</strong>']));
}
} else {
$response['msg'] = __('Error occured, please try again later.');
$response['msg'] = __('Error occurred. Please try again later.');
}
} else {
// Just activate license
@@ -211,36 +304,10 @@ class ModulesController extends Controller
\Session::flash('flash_success_floating', __('License successfully activated!'));
$response['status'] = 'success';
}
} elseif (!empty($result['error'])) {
switch ($result['error']) {
case 'missing':
$response['msg'] = __('License key does not exist');
break;
case 'license_not_activable':
$response['msg'] = __("You have to activate each bundle's module separately");
break;
case 'disabled':
$response['msg'] = __("License key has been revoked");
break;
case 'no_activations_left':
$response['msg'] = __("No activations left for this license key");
break;
case 'expired':
$response['msg'] = __("License key has expired");
break;
case 'key_mismatch':
$response['msg'] = __("License key belongs to another module");
break;
case 'invalid_item_id':
$response['msg'] = __("Module not found in the modules directory");
break;
default:
$response['msg'] = __('Error code:'.' '.$result['error']);
break;
}
$response['msg'] = \App\Module::getErrorMessage($result['error'], $result);
} else {
$response['msg'] = __('Error occured, please try again later.');
$response['msg'] = __('Error occurred. Please try again later.');
}
}
}
@@ -248,27 +315,142 @@ class ModulesController extends Controller
case 'activate':
$alias = $request->alias;
\App\Module::setActive($alias, true);
$module = \Module::findByAlias($alias);
$outputLog = new BufferedOutput;
\Artisan::call('freescout:module-install', ['module_alias' => $alias], $outputLog);
if (!$module) {
$response['msg'] = __('Module not found').': '.$alias;
}
// Check license
if (!$response['msg']) {
if (!empty($module->get('authorUrl')) && $module->isOfficial()) {
$params = [
'license' => $module->getLicense(),
'module_alias' => $alias,
'url' => \App\Module::getAppUrl(),
];
$license_result = WpApi::checkLicense($params);
if (!empty($license_result['code']) && !empty($license_result['message'])) {
// Remove remembered license key and deactivate license in DB
\App\Module::deactivateLicense($alias, '');
$response['msg'] = $license_result['message'];
} elseif (!empty($license_result['status']) && $license_result['status'] != 'valid' && $license_result['status'] != 'inactive') {
// Remove remembered license key and deactivate license in DB
\App\Module::deactivateLicense($alias, '');
switch ($license_result['status']) {
case 'expired':
$response['msg'] = __('License key has expired');
break;
case 'disabled':
$response['msg'] = __('License key has been revoked');
break;
case 'inactive':
$response['msg'] = __('License key has not been activated yet');
case 'site_inactive':
$response['msg'] = __('No activations left for this license key').' ('.__("Use 'Deactivate License' link above to transfer license key from another domain").')';
break;
}
} elseif (!empty($license_result['status']) && $license_result['status'] == 'inactive') {
// Activate the license.
$result = WpApi::activateLicense($params);
if (WpApi::$lastError) {
$response['msg'] = WpApi::$lastError['message'];
} elseif (!empty($result['code']) && !empty($result['message'])) {
$response['msg'] = $result['message'];
} else {
if (!empty($result['status']) && $result['status'] == 'valid') {
// Success.
} elseif (!empty($result['error'])) {
$response['msg'] = \App\Module::getErrorMessage($result['error'], $result);
} else {
// Some unknown error. Do nothing.
}
}
}
}
}
if (!$response['msg']) {
\App\Module::setActive($alias, true);
$outputLog = new BufferedOutput();
\Artisan::call('freescout:module-install', ['module_alias' => $alias], $outputLog);
$output = $outputLog->fetch();
// Get module name
$name = '?';
if ($module) {
$name = $module->getName();
}
$type = 'danger';
$msg = __('Error occurred activating ":name" module', ['name' => $name]);
if (session('flashes_floating') && is_array(session('flashes_floating'))) {
// If there was any error, module has been deactivated via modules.register_error filter
$msg = '';
foreach (session('flashes_floating') as $flash) {
$msg .= $flash['text'].' ';
}
} elseif (strstr($output, 'Configuration cached successfully')) {
$type = 'success';
$msg = __('":name" module successfully activated!', ['name' => $name]);
} else {
// Deactivate the module.
\App\Module::setActive($alias, false);
\Artisan::call('freescout:clear-cache');
}
// Check public folder.
if ($module && file_exists($module->getPath().DIRECTORY_SEPARATOR.'Public')) {
$symlink_path = public_path().\Module::getPublicPath($alias);
if (!file_exists($symlink_path)) {
$type = 'danger';
$msg = 'Error occurred creating a module symlink ('.$symlink_path.'). Please check folder permissions.';
\App\Module::setActive($alias, false);
\Artisan::call('freescout:clear-cache');
}
}
if ($type == 'success') {
// Migrate again, in case migration did not work in the moment the module was activated.
\Artisan::call('migrate', ['--force' => true]);
}
// \Session::flash does not work after BufferedOutput
$flash = [
'text' => '<strong>'.$msg.'</strong><pre class="margin-top">'.$output.'</pre>',
'unescaped' => true,
'type' => $type,
];
\Cache::forever('modules_flash', $flash);
$response['status'] = 'success';
}
break;
case 'deactivate':
$alias = $request->alias;
\App\Module::setActive($alias, false);
$outputLog = new BufferedOutput();
\Artisan::call('freescout:clear-cache', [], $outputLog);
$output = $outputLog->fetch();
// Get module name
$module = \Module::findByAlias($alias);
$name = '?';
if ($module) {
$name = $module->getName();
}
$type = 'danger';
$msg = __('Error occured activating module');
if (session('flashes_floating') && is_array(session('flashes_floating'))) {
// If there was any error, module has been deactivate via modules.register_error filter
$msg = '';
foreach (session('flashes_floating') as $flash) {
$msg .= $flash['text'].' ';
}
} elseif (strstr($output, 'Configuration cached successfully')) {
$msg = __('Error occurred deactivating :name module', ['name' => $name]);
if (strstr($output, 'Configuration cached successfully')) {
$type = 'success';
$msg = __('Module successfully activated!');
} else {
// Deactivate module
\App\Module::setActive($alias, false);
\Artisan::call('freescout:clear-cache');
$msg = __('":name" module successfully Deactivated!', ['name' => $name]);
}
// \Session::flash does not work after BufferedOutput
@@ -281,29 +463,54 @@ class ModulesController extends Controller
$response['status'] = 'success';
break;
case 'deactivate':
case 'deactivate_license':
$license = $request->license;
$alias = $request->alias;
\App\Module::setActive($alias, false);
$outputLog = new BufferedOutput;
\Artisan::call('freescout:clear-cache', [], $outputLog);
$output = $outputLog->fetch();
$type = 'danger';
$msg = __('Error occured deactivating module');
if (strstr($output, 'Configuration cached successfully')) {
$type = 'success';
$msg = __('Module successfully deactivated!');
if (!$license) {
$response['msg'] = __('Empty license key');
}
// \Session::flash does not work after BufferedOutput
$flash = [
'text' => '<strong>'.$msg.'</strong><pre class="margin-top">'.$output.'</pre>',
'unescaped' => true,
'type' => $type,
];
\Cache::forever('modules_flash', $flash);
$response['status'] = 'success';
if (!$response['msg']) {
$params = [
'license' => $license,
'module_alias' => $alias,
'url' => (!empty($request->any_url) ? '*' : \App\Module::getAppUrl()),
];
$result = WpApi::deactivateLicense($params);
if (WpApi::$lastError) {
$response['msg'] = WpApi::$lastError['message'];
} elseif (!empty($result['code']) && !empty($result['message'])) {
$response['msg'] = $result['message'];
} else {
if (!empty($result['status']) && $result['status'] == 'success') {
$db_module = \App\Module::getByAlias($alias);
if ($db_module && trim($db_module->license ?? '') == trim($license ?? '')) {
// Remove remembered license key and deactivate license in DB
\App\Module::deactivateLicense($alias, '');
// Deactivate module
\App\Module::setActive($alias, false);
\Artisan::call('freescout:clear-cache', []);
}
// Flash does not work here.
$flash = [
'text' => '<strong>'.__('License successfully Deactivated!').'</strong>',
'unescaped' => true,
'type' => 'success',
];
\Cache::forever('modules_flash', $flash);
$response['status'] = 'success';
} elseif (!empty($result['error'])) {
$response['msg'] = \App\Module::getErrorMessage($result['error'], $result);
} else {
$response['msg'] = __('Error occurred. Please try again later.');
}
}
}
break;
case 'delete':
@@ -318,19 +525,92 @@ class ModulesController extends Controller
$module->delete();
\Session::flash('flash_success_floating', __('Module deleted'));
} else {
$response['msg'] = __("Module not found").': '.$alias;
$response['msg'] = __('Module not found').': '.$alias;
}
$response['status'] = 'success';
break;
case 'update':
$update_result = \App\Module::updateModule($request->alias);
if ($update_result['download_error']) {
$response['reload'] = true;
if ($update_result['msg']) {
\Session::flash('flash_error_floating', $update_result['msg']);
}
if ($update_result['download_msg']) {
\Session::flash('flash_error_unescaped', $update_result['download_msg']);
}
}
// Install updated module.
if ($update_result['output'] || $update_result['status']) {
$type = 'danger';
$msg = $update_result['msg'];
if ($update_result['status'] == 'success') {
$type = 'success';
$msg = $update_result['msg_success'];
}
// \Session::flash does not work after BufferedOutput
$flash = [
'text' => '<strong>'.$msg.'</strong><pre class="margin-top">'.$update_result['output'].'</pre>',
'unescaped' => true,
'type' => $type,
];
\Cache::forever('modules_flash', $flash);
$response['status'] = 'success';
}
break;
case 'update_all':
$update_all_flashes = [];
foreach ($request->aliases as $alias) {
$update_result = \App\Module::updateModule($alias);
$type = 'danger';
$msg = $update_result['msg'];
if ($update_result['status'] == 'success') {
$type = 'success';
$msg = $update_result['msg_success'];
} elseif ($update_result['download_msg']) {
$msg .= '<br/>'.$update_result['download_msg'];
}
$text = '<strong>'.$update_result['module_name'].':</strong> '.$msg;
if (trim($update_result['output'])) {
$text .= '<pre class="margin-top">'.$update_result['output'].'</pre>';
}
// \Session::flash does not work after BufferedOutput
$update_all_flashes[] = [
'text' => $text,
'unescaped' => true,
'type' => $type,
];
}
if ($update_all_flashes) {
\Cache::forever('modules_flash', $update_all_flashes);
}
$response['status'] = 'success';
break;
default:
$response['msg'] = 'Unknown action';
break;
}
if ($response['status'] == 'error' && empty($response['msg'])) {
$response['msg'] = 'Unknown error occured';
$response['msg'] = 'Unknown error occurred';
}
return \Response::json($response);

View File

@@ -0,0 +1,228 @@
<?php
namespace App\Http\Controllers;
use App\Attachment;
use App\Conversation;
use App\Option;
use App\Thread;
use App\User;
use Illuminate\Http\Request;
use Illuminate\Support\Facades\Auth;
use Validator;
class OpenController extends Controller
{
/**
* Create a new controller instance.
*
* @return void
*/
public function __construct()
{
}
/**
* Setup user from invitation.
*
* @return \Illuminate\Http\Response
*/
public function userSetup($hash)
{
if (auth()->user()) {
return redirect()->route('dashboard');
}
$user = User::where('invite_hash', $hash)->first();
if ($user && $user->locale) {
\Helper::setLocale($user->locale);
}
return view('open/user_setup', ['user' => $user]);
}
/**
* Save user from invitation.
*/
public function userSetupSave($hash, Request $request)
{
if (auth()->user()) {
return redirect()->route('dashboard');
}
$user = User::where('invite_hash', $hash)->first();
if (!$user) {
abort(404);
}
$validator = Validator::make($request->all(), [
'email' => 'required|string|email|max:100|unique:users,email,'.$user->id,
'password' => 'required|string|min:8|confirmed',
'job_title' => 'max:100',
'phone' => 'max:60',
'timezone' => 'required|string|max:255',
'time_format' => 'required',
'photo_url' => 'nullable|image|mimes:jpeg,png,jpg,gif',
]);
$validator->setAttributeNames([
'photo_url' => __('Photo'),
]);
// Photo
$validator->after(function ($validator) use ($user, $request) {
if ($request->hasFile('photo_url')) {
$path_url = $user->savePhoto($request->file('photo_url'));
if ($path_url) {
$user->photo_url = $path_url;
} else {
$validator->errors()->add('photo_url', __('Error occurred processing the image. Make sure that PHP GD extension is enabled.'));
}
}
});
if ($validator->fails()) {
return redirect()->route('user_setup', ['hash' => $hash])
->withErrors($validator)
->withInput();
}
$request_data = $request->all();
// Do not allow user to set his role
if (isset($request_data['role'])) {
unset($request_data['role']);
}
if (isset($request_data['photo_url'])) {
unset($request_data['photo_url']);
}
$user->fill($request_data);
$user->password = bcrypt($request->password);
$user->invite_state = User::INVITE_STATE_ACTIVATED;
$user->invite_hash = '';
$user = \Eventy::filter('user.setup_save', $user, $request);
$user->save();
// Login user
Auth::guard()->login($user);
\Session::flash('flash_success_floating', __('Welcome to :company_name!', ['company_name' => Option::getCompanyName()]));
return redirect()->route('dashboard');
}
/*
* Set a thread as read by customer
*/
public function setThreadAsRead($conversation_id, $thread_id)
{
$conversation = Conversation::findOrFail($conversation_id);
$thread = Thread::findOrFail($thread_id);
// We only track the first opening
if (empty($thread->opened_at)) {
$thread->opened_at = date('Y-m-d H:i:s');
$thread->save();
\Eventy::action('thread.opened', $thread, $conversation);
}
// Create a 1x1 ttransparent pixel and return it
$pixel = sprintf('%c%c%c%c%c%c%c%c%c%c%c%c%c%c%c%c%c%c%c%c%c%c%c%c%c%c%c%c%c%c%c%c%c%c%c%c%c%c%c%c%c%c%c', 71, 73, 70, 56, 57, 97, 1, 0, 1, 0, 128, 255, 0, 192, 192, 192, 0, 0, 0, 33, 249, 4, 1, 0, 0, 0, 0, 44, 0, 0, 0, 0, 1, 0, 1, 0, 0, 2, 2, 68, 1, 0, 59);
$response = \Response::make($pixel, 200);
$response->header('Content-type', 'image/gif');
$response->header('Content-Length', 42);
$response->header('Cache-Control', 'private, no-cache, no-cache=Set-Cookie, proxy-revalidate');
$response->header('Expires', 'Wed, 11 Jan 2000 12:59:00 GMT');
$response->header('Last-Modified', 'Wed, 11 Jan 2006 12:59:00 GMT');
$response->header('Pragma', 'no-cache');
return $response;
}
/**
* Download an attachment.
*/
public function downloadAttachment($dir_1, $dir_2, $dir_3, $file_name, Request $request)
{
$id = $request->query('id', '');
$token = $request->query('token', '');
$attachment = null;
// Old attachments can not be requested by id.
if (!$token && $id) {
return \Helper::denyAccess();
}
// Get attachment by id.
if ($id) {
$attachment = Attachment::findOrFail($id);
}
if (!$attachment) {
$attachment = Attachment::where('file_dir', $dir_1.DIRECTORY_SEPARATOR.$dir_2.DIRECTORY_SEPARATOR.$dir_3.DIRECTORY_SEPARATOR)
->where('file_name', $file_name)
->firstOrFail();
}
// Only allow download if the attachment is public or if the token matches the hash of the contents
if ($token != $attachment->getToken() && (bool)$attachment->public !== true) {
return \Helper::denyAccess();
}
$view_attachment = false;
$file_ext = strtolower(pathinfo($attachment->file_name, PATHINFO_EXTENSION));
// Some file type should be viewed in the browser instead of downloading.
if (in_array($file_ext, config('app.viewable_attachments'))) {
$view_attachment = true;
}
// If HTML file is renamed into .txt for example it will be shown by the browser as HTML.
if ($view_attachment && $attachment->mime_type) {
$allowed_mime_type = false;
foreach (config('app.viewable_mime_types') as $mime_type) {
if (preg_match('#'.$mime_type.'#', $attachment->mime_type)) {
$allowed_mime_type = true;
break;
}
}
if (!$allowed_mime_type) {
$view_attachment = false;
}
}
if (config('app.download_attachments_via') == 'apache') {
// Send using Apache mod_xsendfile.
$response = response(null)
->header('Content-Type' , $attachment->mime_type)
->header('X-Sendfile', $attachment->getLocalFilePath());
if (!$view_attachment) {
$response->header('Content-Disposition', 'attachment; filename="'.$attachment->file_name.'"');
}
} elseif (config('app.download_attachments_via') == 'nginx') {
// Send using Nginx.
$response = response(null)
->header('Content-Type' , $attachment->mime_type)
->header('X-Accel-Redirect', $attachment->getLocalFilePath(false));
if (!$view_attachment) {
$response->header('Content-Disposition', 'attachment; filename="'.$attachment->file_name.'"');
}
} else {
$response = $attachment->download($view_attachment);
}
return $response;
}
/**
* Needed for the mobile app.
*/
// public function mobilePing()
// {
// echo file_get_contents(public_path('installer/css/fontawesome.css'));
// }
}

View File

@@ -1,109 +0,0 @@
<?php
namespace App\Http\Controllers;
use App\Option;
use App\User;
use Illuminate\Http\Request;
use Illuminate\Support\Facades\Auth;
use Validator;
class PublicController extends Controller
{
/**
* Create a new controller instance.
*
* @return void
*/
public function __construct()
{
}
/**
* Setup user from invitation.
*
* @return \Illuminate\Http\Response
*/
public function userSetup($hash)
{
if (auth()->user()) {
return redirect()->route('dashboard');
}
$user = User::where('invite_hash', $hash)->first();
return view('public/user_setup', ['user' => $user]);
}
/**
* Save user from invitation.
*
*/
public function userSetupSave($hash, Request $request)
{
if (auth()->user()) {
return redirect()->route('dashboard');
}
$user = User::where('invite_hash', $hash)->first();
if (!$user) {
abort(404);
}
$validator = Validator::make($request->all(), [
'email' => 'required|string|email|max:100|unique:users,email,'.$user->id,
'password' => 'required|string|min:8|confirmed',
'job_title' => 'max:100',
'phone' => 'max:60',
'timezone' => 'required|string|max:255',
'time_format' => 'required',
'photo_url' => 'nullable|image|mimes:jpeg,png,jpg,gif',
]);
$validator->setAttributeNames([
'photo_url' => __('Photo'),
]);
// Photo
$validator->after(function ($validator) use ($user, $request) {
if ($request->hasFile('photo_url')) {
$path_url = $user->savePhoto($request->file('photo_url'));
if ($path_url) {
$user->photo_url = $path_url;
} else {
$validator->errors()->add('photo_url', __('Error occured processing the image. Make sure that PHP GD extension is enabled.'));
}
}
});
if ($validator->fails()) {
return redirect()->route('user_setup', ['hash' => $hash])
->withErrors($validator)
->withInput();
}
$request_data = $request->all();
// Do not allow user to set his role
if (isset($request_data['role'])) {
unset($request_data['role']);
}
if (isset($request_data['photo_url'])) {
unset($request_data['photo_url']);
}
$user->fill($request_data);
$user->password = bcrypt($request->password);
$user->invite_state = User::INVITE_STATE_ACTIVATED;
$user->invite_hash = '';
$user->save();
// Login user
Auth::guard()->login($user);
\Session::flash('flash_success_floating', __('Welcome to :company_name!', ['company_name' => Option::getCompanyName()]));
return redirect()->route('dashboard');
}
}

View File

@@ -3,11 +3,10 @@
namespace App\Http\Controllers;
use App\ActivityLog;
use App\Option;
use App\Misc\Helper;
use App\SendLog;
use App\Thread;
use App\User;
use Carbon\Carbon;
use Illuminate\Http\Request;
class SecureController extends Controller
@@ -29,7 +28,15 @@ class SecureController extends Controller
*/
public function dashboard()
{
$mailboxes = auth()->user()->mailboxesCanView();
$user = auth()->user();
if (!$user->isAdmin()) {
$mailboxes = $user->mailboxesCanView();
} else {
$mailboxes = $user->mailboxesCanViewWithSettings();
}
// Sort by name.
$mailboxes = \Eventy::filter('dashboard.mailboxes', $mailboxes->sortBy('name'));
return view('secure/dashboard', ['mailboxes' => $mailboxes]);
}
@@ -63,7 +70,7 @@ class SecureController extends Controller
$activities = ActivityLog::inLog($request->name)->orderBy('created_at', 'desc')->paginate($page_size);
$name = $request->name;
} elseif (count($names)) {
$name = ActivityLog::NAME_OUT_EMAILS;
$name = ActivityLog::NAME_OUT_EMAILS;
// $activities = ActivityLog::inLog($names[0])->orderBy('created_at', 'desc')->paginate($page_size);
// $name = $names[0];
}
@@ -105,23 +112,32 @@ class SecureController extends Controller
'type',
'email',
'status',
'conversation',
'message',
'user',
'customer',
];
$activities = SendLog::orderBy('created_at', 'desc')->paginate($page_size);
$activities_query = SendLog::orderBy('created_at', 'desc');
if ($request->get('thread_id')) {
$activities_query->where('thread_id', $request->get('thread_id'));
}
$activities = $activities_query->paginate($page_size);
foreach ($activities as $record) {
$conversation = '';
if ($record->thread_id) {
$conversation = Thread::find($record->thread_id);
}
$status = $record->getStatusName();
if ($record->status_message) {
$status .= '. '.$record->status_message;
if ($record->status == SendLog::STATUS_SEND_ERROR) {
$status .= '. Message-ID: '.$record->message_id;
}
}
if ($record->smtp_queue_id) {
$status .= '. SMTP ID: '.$record->smtp_queue_id;
}
$logs[] = [
@@ -129,12 +145,11 @@ class SecureController extends Controller
'type' => $record->getMailTypeName(),
'email' => $record->email,
'status' => $status,
'conversation' => $conversation,
'message' => $conversation,
'user' => $record->user,
'customer' => $record->customer,
];
}
}
array_unshift($names, ActivityLog::NAME_OUT_EMAILS);
@@ -145,16 +160,16 @@ class SecureController extends Controller
}
return view('secure/logs', [
'logs' => $logs,
'names' => $names,
'logs' => $logs,
'names' => $names,
'current_name' => $name,
'cols' => $cols,
'activities' => $activities
'cols' => $cols,
'activities' => $activities,
]);
}
/**
* Logs page submitted
* Logs page submitted.
*/
public function logsSubmit(Request $request)
{
@@ -162,10 +177,10 @@ class SecureController extends Controller
$name = '';
if (!empty($request->name)) {
$activities = ActivityLog::inLog($request->name)->orderBy('created_at', 'desc')->get();
//$activities = ActivityLog::inLog($request->name)->orderBy('created_at', 'desc')->get();
$name = $request->name;
} elseif (count($names = ActivityLog::select('log_name')->distinct()->get()->pluck('log_name'))) {
$name = ActivityLog::NAME_OUT_EMAILS;
$name = ActivityLog::NAME_OUT_EMAILS;
// $activities = ActivityLog::inLog($names[0])->orderBy('created_at', 'desc')->get();
// $name = $names[0];
}
@@ -181,4 +196,41 @@ class SecureController extends Controller
return redirect()->route('logs', ['name' => $name]);
}
/**
* Upload files and images.
*/
public function upload(Request $request, $allowed_exts = [])
{
// 'jpg','gif','png'
$response = [
'status' => 'error',
'msg' => '', // this is error message
];
$user = auth()->user();
if (!$user) {
$response['msg'] = __('Please login to upload file');
}
if (!$request->hasFile('file') || !$request->file('file')->isValid() || !$request->file) {
$response['msg'] = __('Error occurred uploading file');
}
if (!$response['msg']) {
$upload = Helper::uploadFile($request->file, $allowed_exts);
$filename = basename($upload);
if ($upload) {
$response['status'] = 'success';
$response['url'] = Helper::uploadedFileUrl($filename);
} else {
$response['msg'] = __('Error occurred uploading file');
}
}
return \Response::json($response);
}
}

View File

@@ -2,10 +2,11 @@
namespace App\Http\Controllers;
use App\Conversation;
use App\Option;
use App\Subscription;
use App\User;
use Illuminate\Http\Request;
use Illuminate\Validation\Rule;
use Validator;
class SettingsController extends Controller
@@ -21,12 +22,12 @@ class SettingsController extends Controller
}
/**
* General settings
* General settings.
*
* @return \Illuminate\Http\Response
*/
public function view($section = 'general')
{
{
$settings = $this->getSectionSettings($section);
if (!$settings) {
@@ -36,10 +37,10 @@ class SettingsController extends Controller
$sections = $this->getSections();
$template_vars = [
'settings' => $settings,
'section' => $section,
'sections' => $this->getSections(),
'section_name' => $sections[$section]['title']
'settings' => $settings,
'section' => $section,
'sections' => $this->getSections(),
'section_name' => $sections[$section]['title'],
];
$template_vars = $this->getTemplateVars($section, $template_vars);
@@ -48,81 +49,203 @@ class SettingsController extends Controller
public function getValidator($section)
{
switch ($section) {
case 'emails':
$rules = [
'settings.mail_from' => 'required|email',
];
break;
// default:
// $rules = \Event::fire('filter.settings_validate_rules');
// break;
}
$rules = $this->getSectionParams($section, 'validator_rules');
if (!empty($rules)) {
return Validator::make(request()->all(), $rules);
}
return null;
}
public function getTemplateVars($section, $template_vars)
{
$section_vars = $this->getSectionParams($section, 'template_vars');
if ($section_vars && is_array($section_vars)) {
return array_merge($template_vars, $section_vars);
} else {
return $template_vars;
}
}
/**
* Parameters of the sections settings.
*
* If in settings parameter `env` is set, option will be saved into .env file
* instead of DB.
*
* @param [type] $section [description]
* @param string $param [description]
*
* @return [type] [description]
*/
public function getSectionParams($section, $param = '')
{
$params = [];
switch ($section) {
case 'emails':
$template_vars['sendmail_path'] = ini_get('sendmail_path');
$template_vars['mail_drivers'] = [
'mail' => __("PHP's mail() function"),
'sendmail' => __("Sendmail"),
'smtp' => 'SMTP',
$params = [
'template_vars' => [
'sendmail_path' => ini_get('sendmail_path'),
'mail_drivers' => [
'mail' => __("PHP's mail() function"),
'sendmail' => __('Sendmail'),
'smtp' => 'SMTP',
],
],
'validator_rules' => [
'settings.mail_from' => 'required|email',
],
'settings' => [
'fetch_schedule' => [
'env' => 'APP_FETCH_SCHEDULE',
],
'mail_password' => [
'safe_password' => true,
'encrypt' => true,
],
// 'use_mail_date_on_fetching' => [
// 'env' => 'APP_USE_MAIL_DATE_ON_FETCHING',
// ],
],
];
break;
// default:
// $template_vars = \Event::fire('filter.settings_template_vars', [$template_vars]);
// break;
case 'general':
$params = [
'settings' => [
'custom_number' => [
'env' => 'APP_CUSTOM_NUMBER',
],
'max_message_size' => [
'env' => 'APP_MAX_MESSAGE_SIZE',
],
'email_conv_history' => [
'env' => 'APP_EMAIL_CONV_HISTORY',
],
'email_user_history' => [
'env' => 'APP_EMAIL_USER_HISTORY',
],
'locale' => [
'env' => 'APP_LOCALE',
],
'timezone' => [
'env' => 'APP_TIMEZONE',
],
'user_permissions' => [
'env' => 'APP_USER_PERMISSIONS',
'env_encode' => true,
],
],
];
break;
case 'alerts':
$subscriptions_defaults = Subscription::getDefaultSubscriptions();
$subscriptions = array();
foreach ($subscriptions_defaults as $medium => $subscriptions_for_medium) {
foreach ($subscriptions_defaults[$medium] as $subscription) {
$subscriptions[] = (object) array("medium" => $medium, "event" => $subscription);
}
}
$params = [
'template_vars' => [
'logs' => \App\ActivityLog::getAvailableLogs(),
'person' => null,
'subscriptions' => $subscriptions,
'mobile_available' => \Eventy::filter('notifications.mobile_available', false),
],
'settings' => [
'alert_logs' => [
'env' => 'APP_ALERT_LOGS',
],
'alert_logs_period' => [
'env' => 'APP_ALERT_LOGS_PERIOD',
],
],
];
// todo: monitor App Logs
foreach ($params['template_vars']['logs'] as $i => $log) {
if ($log == \App\ActivityLog::NAME_APP_LOGS || $log == \App\ActivityLog::NAME_OUT_EMAILS) {
unset($params['template_vars']['logs'][$i]);
}
}
break;
default:
$params = \Eventy::filter('settings.section_params', $params, $section);
break;
}
return $template_vars;
$params = \Eventy::filter('settings.alter_section_params', $params, $section);
if ($param) {
if (isset($params[$param])) {
return $params[$param];
} else {
return;
}
} else {
return $params;
}
}
public function getSectionSettings($section)
{
$settings = [];
switch ($section) {
case 'general':
$settings = [
'company_name' => Option::get('company_name', \Config::get('app.name')),
'next_ticket' => Option::get('next_ticket'),
'user_permissions' => Option::get('user_permissions', []),
'next_ticket' => (Option::get('next_ticket') >= Conversation::max('number') + 1) ? Option::get('next_ticket') : Conversation::max('number') + 1,
'custom_number' => (int)config('app.custom_number'),
'user_permissions' => User::getGlobalUserPermissions(),
'email_branding' => Option::get('email_branding'),
'open_tracking' => Option::get('open_tracking'),
'email_conv_history' => config('app.email_conv_history'),
'max_message_size' => config('app.max_message_size'),
'email_user_history' => config('app.email_user_history'),
'enrich_customer_data' => Option::get('enrich_customer_data'),
'time_format' => Option::get('time_format', User::TIME_FORMAT_24),
'locale' => \Helper::getRealAppLocale(),
'timezone' => config('app.timezone'),
];
break;
case 'emails':
$settings = [
'mail_from' => \App\Misc\Mail::getSystemMailFrom(),
'mail_driver' => Option::get('mail_driver', \Config::get('mail.driver')),
'mail_host' => Option::get('mail_host', \Config::get('mail.host')),
'mail_port' => Option::get('mail_port', \Config::get('mail.port')),
'mail_username' => Option::get('mail_username', \Config::get('mail.username')),
'mail_password' => Option::get('mail_password', \Config::get('mail.password')),
'mail_from' => \App\Misc\Mail::getSystemMailFrom(),
'mail_driver' => Option::get('mail_driver', \Config::get('mail.driver')),
'mail_host' => Option::get('mail_host', \Config::get('mail.host')),
'mail_port' => Option::get('mail_port', \Config::get('mail.port')),
'mail_username' => Option::get('mail_username', \Config::get('mail.username')),
'mail_password' => \Helper::decrypt(Option::get('mail_password', \Config::get('mail.password'))),
'mail_encryption' => Option::get('mail_encryption', \Config::get('mail.encryption')),
'fetch_schedule' => config('app.fetch_schedule'),
//'use_mail_date_on_fetching' => config('app.use_mail_date_on_fetching'),
];
break;
case 'alerts':
$settings = [
'alert_recipients' => Option::get('alert_recipients'),
'alert_fetch' => Option::get('alert_fetch'),
'alert_fetch_period' => Option::get('alert_fetch_period'),
'alert_send' => Option::get('alert_send'),
];
$settings = Option::getOptions([
'alert_recipients',
'alert_fetch',
'alert_fetch_period',
'alert_logs',
'alert_logs_names',
'alert_logs_period',
'subscription_defaults',
], [
'alert_logs_names' => [],
'alert_logs' => config('app.alert_logs'),
'alert_logs_period' => config('app.alert_logs_period'),
]);
break;
default:
$settings = \Event::fire('filter.section_settings', [$section]);
$settings = \Eventy::filter('settings.section_settings', $settings, $section);
break;
}
$settings = \Eventy::filter('settings.alter_section_settings', $settings, $section);
return $settings;
}
@@ -134,7 +257,8 @@ class SettingsController extends Controller
'emails' => ['title' => __('Mail Settings'), 'icon' => 'transfer', 'order' => 200],
'alerts' => ['title' => __('Alerts'), 'icon' => 'bell', 'order' => 300],
];
//return \Event::fire('filter.settings_sections', [$sections]);
$sections = \Eventy::filter('settings.sections', $sections);
return $sections;
}
@@ -167,25 +291,85 @@ class SettingsController extends Controller
$request = request();
$request->settings = array_merge($request->settings, [
'email_branding' => !empty($request->settings['email_branding']) ? $request->settings['email_branding'] : 0,
'open_tracking' => !empty($request->settings['open_tracking']) ? $request->settings['open_tracking'] : 0,
'enrich_customer_data' => !empty($request->settings['enrich_customer_data']) ? $request->settings['enrich_customer_data'] : 0,
]);
$request = \Eventy::filter('settings.before_save', $request, $section, $settings);
$cc_required = false;
$settings_params = $this->getSectionParams($section, 'settings');
foreach ($settings as $i => $option_name) {
// By some reason isset() does not work for empty elements
if (array_key_exists($option_name, $request->settings)) {
// Do not save dummy passwords.
if (!empty($settings_params[$option_name])
&& !empty($settings_params[$option_name]['safe_password'])
&& $request->settings[$option_name]
&& preg_match("/^\*+$/", $request->settings[$option_name])
) {
continue;
}
// Option has to be saved to .env file.
if (!empty($settings_params[$option_name]) && !empty($settings_params[$option_name]['env'])) {
$env_value = $request->settings[$option_name] ?? '';
if (is_array($env_value)) {
$env_value = json_encode($env_value);
}
if (!empty($settings_params[$option_name]['encrypt'])) {
$env_value = encrypt($env_value);
}
if (!empty($settings_params[$option_name]['env_encode'])) {
$env_value = base64_encode($env_value);
}
\Helper::setEnvFileVar($settings_params[$option_name]['env'], $env_value);
config($option_name, $env_value);
$cc_required = true;
continue;
}
// By some reason isset() does not work for empty elements.
if (isset($request->settings) && array_key_exists($option_name, $request->settings)) {
$option_value = $request->settings[$option_name];
if (!empty($settings_params[$option_name]['encrypt'])) {
$option_value = encrypt($option_value);
}
Option::set($option_name, $option_value);
} else {
Option::remove($option_name);
// If option does not exist, default will be used,
// so we can not just remove bool settings.
if (isset($settings_params[$option_name]['default'])) {
$default = $settings_params[$option_name]['default'];
} else {
$default = \Option::getDefault($option_name, null);
}
if ($default === true) {
Option::set($option_name, false);
} elseif (is_array(\Option::getDefault($option_name, -1))) {
Option::set($option_name, []);
} else {
Option::remove($option_name);
}
}
}
\Session::flash('flash_success_floating', __('Settings updated'));
// Clear cache if some options have been saved to .env file.
// Clearing the cache also restarts queue:work as it also
// needs to get new .env parameters.
if ($cc_required) {
\Helper::clearCache(['--doNotGenerateVars' => true]);
}
return redirect()->route('settings', ['section' => $section]);
// \Helper::clearCache prevents \Session::flash() from displaying.
$request->session()->flash('flash_success_floating', __('Settings updated'));
$response = redirect()->route('settings', ['section' => $section]);
$response = \Eventy::filter('settings.after_save', $response, $request, $section, $settings);
return $response;
}
/**
@@ -210,17 +394,22 @@ class SettingsController extends Controller
}
if (!$response['msg']) {
$test_result = false;
$test_result = [
'status' => 'error'
];
try {
$test_result = \MailHelper::sendTestMail($request->to);
} catch (\Exception $e) {
$response['msg'] = $e->getMessage();
$test_result['msg'] = $e->getMessage();
}
if (!$test_result && !$response['msg']) {
$response['msg'] = __('Error occurend sending email. Please check your mail server logs for more details.');
if ($test_result['status'] == 'error') {
$response['msg'] = $test_result['msg']
?: __('Error occurred sending email. Please check your mail server logs for more details.');
}
$response['log'] = $test_result['log'] ?? '';
}
if (!$response['msg']) {
@@ -239,7 +428,7 @@ class SettingsController extends Controller
}
if ($response['status'] == 'error' && empty($response['msg'])) {
$response['msg'] = 'Unknown error occured';
$response['msg'] = 'Unknown error occurred';
}
return \Response::json($response);

View File

@@ -4,12 +4,15 @@ namespace App\Http\Controllers;
use App\Option;
use App\User;
use App\FailedJob;
use Carbon\Carbon;
use Illuminate\Http\Request;
use Symfony\Component\Console\Output\BufferedOutput;
class SystemController extends Controller
{
public static $latest_version_error = '';
/**
* Create a new controller instance.
*
@@ -17,7 +20,9 @@ class SystemController extends Controller
*/
public function __construct()
{
$this->middleware('auth');
$this->middleware('auth', ['except' => [
'cron'
]]);
}
/**
@@ -25,29 +30,66 @@ class SystemController extends Controller
*/
public function status(Request $request)
{
// PHP extensions
$php_extensions = [];
foreach (\Config::get('app.required_extensions') as $extension_name) {
$alternatives = explode('/', $extension_name);
if ($alternatives) {
foreach ($alternatives as $alternative) {
$php_extensions[$extension_name] = extension_loaded(trim($alternative));
if ($php_extensions[$extension_name]) {
break;
}
}
} else {
$php_extensions[$extension_name] = extension_loaded($extension_name);
// PHP extensions.
$php_extensions = \Helper::checkRequiredExtensions();
// Functions.
$functions = \Helper::checkRequiredFunctions();
// Permissions.
$permissions = [];
foreach (config('installer.permissions') as $perm_path => $perm_value) {
$path = base_path($perm_path);
$value = '';
if (file_exists($path)) {
$value = substr(sprintf('%o', fileperms($path)), -4);
}
$permissions[$perm_path] = [
'status' => \Helper::isFolderWritable($path),
'value' => $value,
];
}
// Check if cache files are writable.
$non_writable_cache_file = '';
if (function_exists('shell_exec')) {
$non_writable_cache_file = \Helper::shellExec('find '.base_path('storage/framework/cache/data/').' -type f | xargs -I {} sh -c \'[ ! -w "{}" ] && echo {}\' 2>&1 | head -n 1');
$non_writable_cache_file = trim($non_writable_cache_file ?? '');
// Leave only one line (in case head -n 1 does not work)
$non_writable_cache_file = preg_replace("#[\r\n].+#m", '', $non_writable_cache_file);
if (!strstr($non_writable_cache_file, base_path('storage/framework/cache/data/'))) {
$non_writable_cache_file = '';
}
}
// Check if public symlink exists, if not, try to create.
$public_symlink_exists = true;
$public_path = public_path('storage');
$public_test = $public_path.DIRECTORY_SEPARATOR.'.gitignore';
if (!file_exists($public_test) || !file_get_contents($public_test)) {
\File::delete($public_path);
\Artisan::call('storage:link');
if (!file_exists($public_test) || !file_get_contents($public_test)) {
$public_symlink_exists = false;
}
}
// Check if .env is writable.
$env_is_writable = is_writable(base_path('.env'));
// Jobs
$queued_jobs = \App\Job::orderBy('created_at', 'desc')->get();
$failed_jobs = \App\FailedJob::orderBy('failed_at', 'desc')->get();
$queued_jobs = \App\Job::orderBy('created_at', 'desc')->limit(100)->get();
$failed_jobs = \App\FailedJob::orderBy('failed_at', 'desc')->limit(100)->get();
$failed_queues = $failed_jobs->pluck('queue')->unique();
// Commands
$commands_list = ['freescout:fetch-emails', 'queue:work'];
foreach ($commands_list as $command_name) {
$commands_list = [
'freescout:fetch-emails' => 'freescout:fetch-emails',
\Helper::getWorkerIdentifier() => 'queue:work'
];
foreach ($commands_list as $command_identifier => $command_name) {
$status_texts = [];
// Check if command is running now
@@ -55,10 +97,16 @@ class SystemController extends Controller
$running_commands = 0;
try {
$processes = preg_split("/[\r\n]/", shell_exec("ps aux | grep '{$command_name}'"));
$processes = preg_split("/[\r\n]/", \Helper::shellExec("ps auxww | grep '{$command_identifier}'"));
$pids = [];
foreach ($processes as $process) {
$process = trim($process);
preg_match("/^[\S]+\s+([\d]+)\s+/", $process, $m);
if (empty($m)) {
// Another format (used in Docker image).
// 1713 nginx 0:00 /usr/bin/php82...
preg_match("/^([\d]+)\s+[\S]+\s+/", $process, $m);
}
if (!preg_match("/(sh \-c|grep )/", $process) && !empty($m[1])) {
$running_commands++;
$pids[] = $m[1];
@@ -77,7 +125,7 @@ class SystemController extends Controller
} elseif ($running_commands > 1) {
// queue:work command is stopped by settings a cache key
if ($command_name == 'queue:work') {
\Cache::forever('illuminate:queue:restart', Carbon::now()->getTimestamp());
\Helper::queueWorkerRestart();
$commands[] = [
'name' => $command_name,
'status' => 'error',
@@ -120,9 +168,10 @@ class SystemController extends Controller
}
// If queue:work is not running, clear cache to let it start if something is wrong with the mutex
if ($command_name == 'queue:work' && !$last_successful_run && function_exists('shell_exec')) {
$status_texts[] = __('Cleared cache to force command to start.');
\Artisan::call('cache:clear');
if ($command_name == 'queue:work' && !$last_successful_run) {
$status_texts[] = __('Try to :%a_start%clear cache:%a_end% to force command to start.', ['%a_start%' => '<a href="'.route('system.tools').'" target="_blank">', '%a_end%' => '</a>']);
// This sometimes makes Status page open as non logged in user.
//\Artisan::call('freescout:clear-cache', ['--doNotGenerateVars' => true]);
}
$commands[] = [
@@ -132,24 +181,80 @@ class SystemController extends Controller
];
}
// Check new version
// Check new version if enabled
$new_version_available = false;
$latest_version = \Cache::remember('latest_version', 15, function() {
return \Updater::getVersionAvailable();
});
if ($latest_version && $latest_version != \Config::get('app.version')) {
$new_version_available = true;
if (!\Config::get('app.disable_updating')) {
$latest_version = \Cache::remember('latest_version', 15, function () {
try {
return \Updater::getVersionAvailable();
} catch (\Exception $e) {
SystemController::$latest_version_error = $e->getMessage();
return '';
}
});
if ($latest_version && version_compare($latest_version, \Config::get('app.version'), '>')) {
$new_version_available = true;
}
} else {
$latest_version = \Config::get('app.version');
}
// Detect missing migrations.
$migrations_output = \Helper::runCommand('migrate:status');
preg_match_all("#\| N \| ([^\|]+)\|#", $migrations_output, $migrations_m);
$missing_migrations = $migrations_m[1] ?? [];
return view('system/status', [
'commands' => $commands,
'queued_jobs' => $queued_jobs,
'failed_jobs' => $failed_jobs,
'php_extensions' => $php_extensions,
'commands' => $commands,
'queued_jobs' => $queued_jobs,
'failed_jobs' => $failed_jobs,
'failed_queues' => $failed_queues,
'php_extensions' => $php_extensions,
'functions' => $functions,
'permissions' => $permissions,
'new_version_available' => $new_version_available,
'latest_version' => $latest_version,
'latest_version_error' => SystemController::$latest_version_error,
'public_symlink_exists' => $public_symlink_exists,
'env_is_writable' => $env_is_writable,
'non_writable_cache_file' => $non_writable_cache_file,
'missing_migrations' => $missing_migrations,
'invalid_symlinks' => \App\Module::checkSymlinks(),
]);
}
public function action(Request $request)
{
switch ($request->action) {
case 'cancel_job':
\App\Job::where('id', $request->job_id)->delete();
\Session::flash('flash_success_floating', __('Done'));
break;
case 'retry_job':
\App\Job::where('id', $request->job_id)->update(['available_at' => time()]);
sleep(1);
\Session::flash('flash_success_floating', __('Done'));
break;
case 'delete_failed_jobs':
\App\FailedJob::where('queue', $request->failed_queue)->delete();
\Session::flash('flash_success_floating', __('Failed jobs deleted'));
break;
case 'retry_failed_jobs':
$jobs = \App\FailedJob::where('queue', $request->failed_queue)->get();
foreach ($jobs as $job) {
\Artisan::call('queue:retry', ['id' => $job->id]);
}
\Session::flash('flash_success_floating', __('Failed jobs restarted'));
break;
}
return redirect()->route('system');
}
/**
* System tools.
*/
@@ -161,18 +266,20 @@ class SystemController extends Controller
}
return view('system/tools', [
'output' => $output
'output' => $output,
]);
}
/**
* Execute tools action.
* @param Request $request [description]
* @return [type] [description]
*
* @param Request $request [description]
*
* @return [type] [description]
*/
public function toolsExecute(Request $request)
{
$outputLog = new BufferedOutput;
$outputLog = new BufferedOutput();
switch ($request->action) {
case 'clear_cache':
@@ -180,7 +287,19 @@ class SystemController extends Controller
break;
case 'fetch_emails':
\Artisan::call('freescout:fetch-emails', [], $outputLog);
$params = [];
$params['--days'] = (int)$request->days;
$params['--unseen'] = (int)$request->unseen;
$params['--debug'] = (int)$request->debug;
\Artisan::call('freescout:fetch-emails', $params, $outputLog);
break;
case 'migrate_db':
\Artisan::call('migrate', ['--force' => true], $outputLog);
break;
case 'logout_users':
\Artisan::call('freescout:logout-users', [], $outputLog);
break;
}
@@ -192,7 +311,7 @@ class SystemController extends Controller
\Cache::forever('tools_execute_output', $output);
}
return redirect()->route('system.tools');
return redirect()->route('system.tools')->withInput($request->input());
}
/**
@@ -210,26 +329,34 @@ class SystemController extends Controller
case 'update':
try {
$status = \Updater::update();
// Artisan::output()
} catch (\Exception $e) {
$response['msg'] = __('Error occured').': '.$e->getMessage();
$response['msg'] = __('Error occurred. Please try again or try another :%a_start%update method:%a_end%', ['%a_start%' => '<a href="'.config('app.freescout_url').'/docs/update/" target="_blank">', '%a_end%' => '</a>']);
$response['msg'] .= '<br/><br/>'.$e->getMessage();
\Helper::logException($e);
}
if (!$response['msg'] && $status) {
// Adding session flash is useless as cache is cleated
// Adding session flash is useless as cache is cleared
$response['msg_success'] = __('Application successfully updated');
$response['status'] = 'success';
}
break;
case 'check_updates':
try {
$response['new_version_available'] = \Updater::isNewVersionAvailable(config('app.version'));
$response['status'] = 'success';
} catch (\Exception $e) {
$response['msg'] = __('Error occured').': '.$e->getMessage();
}
if (!$response['msg'] && !$response['new_version_available']) {
// Adding session flash is useless as cache is cleated
if (!\Config::get('app.disable_updating')) {
try {
$response['new_version_available'] = \Updater::isNewVersionAvailable(config('app.version'));
$response['status'] = 'success';
} catch (\Exception $e) {
$response['msg'] = __('Error occurred').': '.$e->getMessage();
}
if (!$response['msg'] && !$response['new_version_available']) {
// Adding session flash is useless as cache is cleated
$response['msg_success'] = __('You have the latest version installed');
}
} else {
$response['msg_success'] = __('You have the latest version installed');
}
break;
@@ -240,9 +367,51 @@ class SystemController extends Controller
}
if ($response['status'] == 'error' && empty($response['msg'])) {
$response['msg'] = 'Unknown error occured';
$response['msg'] = 'Unknown error occurred';
}
return \Response::json($response);
}
/**
* Web Cron.
*/
public function cron(Request $request)
{
if (empty($request->hash) || $request->hash != \Helper::getWebCronHash()) {
abort(404);
}
$outputLog = new BufferedOutput();
\Artisan::call('schedule:run', [], $outputLog);
$output = $outputLog->fetch();
return response($output, 200)->header('Content-Type', 'text/plain');
}
/**
* Ajax HTML.
*/
public function ajaxHtml(Request $request)
{
switch ($request->action) {
case 'job_details':
$job = \App\FailedJob::find($request->param);
if (!$job) {
abort(404);
}
$html = '';
$payload = json_decode($job->payload, true);
if (!empty($payload['data']['command'])) {
$html .= '<pre>'.print_r(unserialize($payload['data']['command']), 1).'</pre>';
}
$html .= '<pre>'.$job->exception.'</pre>';
return response($html);
}
abort(404);
}
}

View File

@@ -2,24 +2,44 @@
namespace App\Http\Controllers;
use \Barryvdh\TranslationManager\Models\Translation;
use Barryvdh\TranslationManager\Controller as BaseController;
class TranslateController extends BaseController
{
/**
* Send translations to FreeScout team.
*
* @return [type] [description]
*/
public function postSend()
{
$result = false;
// Count changed translations.
$changed_data = Translation::select(['locale', 'group', \DB::raw('count(*) as changed')])
->where('status', Translation::STATUS_CHANGED)
->groupBy(['locale', 'group'])
->get()
->toArray();
$this->manager->exportTranslations('*', false);
// Archive langs folder
$archive_path = \Helper::createZipArchive(base_path().DIRECTORY_SEPARATOR.'resources/lang', 'lang.zip', 'lang');
try {
$archive_path = \Helper::createZipArchive(base_path().DIRECTORY_SEPARATOR.'resources/lang', 'lang.zip', 'lang');
} catch (\Exception $e) {
return [
'status' => 'error',
'error_msg' => $e->getMessage(),
];
}
if ($archive_path) {
$attachments[] = $archive_path;
// Send archive to developers
$result = \MailHelper::sendEmailToDevs('Translations', '', $attachments, auth()->user());
$result = \MailHelper::sendEmailToDevs('Translations', json_encode($changed_data), $attachments, auth()->user());
}
if ($result) {
@@ -28,4 +48,47 @@ class TranslateController extends BaseController
abort(500);
}
}
/**
* Remove all translations which has not been published yet.
*
* @return [type] [description]
*/
public function postRemoveUnpublished()
{
\Barryvdh\TranslationManager\Models\Translation::truncate();
return ['status' => 'ok'];
}
/**
* Download as ZIP.
*
* @return [type] [description]
*/
public function postDownload()
{
$this->manager->exportTranslations('*', false);
$file_name = 'lang.zip';
// Archive langs folder
$archive_path = \Helper::createZipArchive(base_path().DIRECTORY_SEPARATOR.'resources/lang', $file_name, 'lang');
$public_path = storage_path('app/public/'.$file_name);
\File::copy($archive_path, $public_path);
$headers = [
'Content-Type: application/zip',
];
return \Response::download($public_path, $file_name, $headers);
}
/**
* List of strings to translate.
*/
public function stringsToTranslate()
{
__(':field is required');
__('The following modules have to be installed and activated: :modules');
}
}

View File

@@ -2,10 +2,10 @@
namespace App\Http\Controllers;
use App\Events\UserDeleted;
use App\Folder;
use App\Mailbox;
use App\Subscription;
use App\Thread;
use App\User;
use Illuminate\Http\Request;
use Illuminate\Support\Facades\Hash;
@@ -32,7 +32,8 @@ class UsersController extends Controller
{
$this->authorize('create', 'App\User');
$users = User::all();
$users = User::nonDeleted()->get();
$users = User::sortUsers($users);
return view('users/users', ['users' => $users]);
}
@@ -55,21 +56,30 @@ class UsersController extends Controller
*/
public function createSave(Request $request)
{
$invalid = false;
$this->authorize('create', 'App\User');
$auth_user = auth()->user();
$rules = [
'role' => 'integer',
'first_name' => 'required|string|max:20',
'last_name' => 'required|string|max:30',
'email' => 'required|string|email|max:100|unique:users',
'role' => ['required', Rule::in(array_keys(User::$roles))],
//'role' => ['required', Rule::in(array_keys(User::$roles))],
];
if ($auth_user->isAdmin()) {
$rules['role'] = ['required', Rule::in(array_keys(User::$roles))];
}
if (empty($request->send_invite)) {
$rules['password'] = 'required|string|max:255';
}
$validator = Validator::make($request->all(), $rules);
if ($validator->fails()) {
if (User::mailboxEmailExists($request->email)) {
$invalid = true;
$validator->errors()->add('email', __('There is a mailbox with such email. Users and mailboxes can not have the same email addresses.'));
}
if ($invalid || $validator->fails()) {
return redirect()->route('users.create')
->withErrors($validator)
->withInput();
@@ -77,6 +87,9 @@ class UsersController extends Controller
$user = new User();
$user->fill($request->all());
if (!$auth_user->can('changeRole', $user)) {
$user->role = User::ROLE_USER;
}
if (empty($request->send_invite)) {
// Set password from request
$user->password = Hash::make($request->password);
@@ -84,9 +97,12 @@ class UsersController extends Controller
// Set some random password before sending invite
$user->password = Hash::make($user->generateRandomPassword());
}
// Set system timezone.
$user->timezone = config('app.timezone') ?: User::DEFAULT_TIMEZONE;
$user = \Eventy::filter('user.create_save', $user, $request);
$user->save();
$user->mailboxes()->sync($request->mailboxes);
$user->mailboxes()->sync($request->mailboxes ?: []);
$user->syncPersonalFolders($request->mailboxes);
// Send invite
@@ -95,7 +111,7 @@ class UsersController extends Controller
$user->sendInvite(true);
} catch (\Exception $e) {
// Admin is allowed to see exceptions
\Session::flash('flash_error_floating', $e->getMessage());
\Session::flash('flash_error_floating', $e->getMessage().' — '.__('Check mail settings in "Manage » Settings » Mail Settings"'));
}
}
@@ -110,6 +126,9 @@ class UsersController extends Controller
public function profile($id)
{
$user = User::findOrFail($id);
if ($user->isDeleted()) {
abort(404);
}
$this->authorize('update', $user);
@@ -121,7 +140,7 @@ class UsersController extends Controller
public function getUsersForSidebar($except_id)
{
if (auth()->user()->isAdmin()) {
return User::all()->except($except_id);
return User::sortUsers(User::nonDeleted()->get());/*->except($except_id)*/;
} else {
return [];
}
@@ -136,6 +155,8 @@ class UsersController extends Controller
*/
public function profileSave($id, Request $request)
{
$invalid = false;
$user = User::findOrFail($id);
$this->authorize('update', $user);
@@ -144,7 +165,7 @@ class UsersController extends Controller
'first_name' => 'required|string|max:20',
'last_name' => 'required|string|max:30',
'email' => 'required|string|email|max:100|unique:users,email,'.$id,
'emails' => 'max:100',
//'emails' => 'max:100',
'job_title' => 'max:100',
'phone' => 'max:60',
'timezone' => 'required|string|max:255',
@@ -164,7 +185,8 @@ class UsersController extends Controller
if ($path_url) {
$user->photo_url = $path_url;
} else {
$validator->errors()->add('photo_url', __('Error occured processing the image. Make sure that PHP GD extension is enabled.'));
$invalid = true;
$validator->errors()->add('photo_url', __('Error occurred processing the image. Make sure that PHP GD extension is enabled.'));
}
}
@@ -172,17 +194,28 @@ class UsersController extends Controller
if ($user->isAdmin() && isset($request->role) && $request->role != User::ROLE_ADMIN) {
$admins_count = User::where('role', User::ROLE_ADMIN)->count();
if ($admins_count < 2) {
$invalid = true;
$validator->errors()->add('role', __('Role of the only one administrator can not be changed.'));
}
}
});
if ($validator->fails()) {
if (User::mailboxEmailExists($request->email)) {
$invalid = true;
$validator->errors()->add('email', __('There is a mailbox with such email. Users and mailboxes can not have the same email addresses.'));
}
if ($invalid || $validator->fails()) {
return redirect()->route('users.profile', ['id' => $id])
->withErrors($validator)
->withInput();
}
// Save language into session.
if (auth()->user()->id == $id && $request->locale) {
session()->put('user_locale', $request->locale);
}
$request_data = $request->all();
if (isset($request_data['photo_url'])) {
@@ -191,12 +224,21 @@ class UsersController extends Controller
if (!auth()->user()->can('changeRole', $user)) {
unset($request_data['role']);
}
$user->fill($request_data);
if ($user->status != User::STATUS_DELETED) {
if (!empty($request_data['disabled'])) {
$request_data['status'] = User::STATUS_DISABLED;
} else {
$request_data['status'] = User::STATUS_ACTIVE;
}
}
$user->setData($request_data);
if (empty($request->input('enable_kb_shortcuts'))) {
$user->enable_kb_shortcuts = false;
}
$user = \Eventy::filter('user.save_profile', $user, $request);
$user->save();
\Session::flash('flash_success_floating', __('Profile saved successfully'));
@@ -216,13 +258,17 @@ class UsersController extends Controller
$user = User::findOrFail($id);
if ($user->isDeleted()) {
abort(404);
}
$mailboxes = Mailbox::all();
$users = $this->getUsersForSidebar($id);
return view('users/permissions', [
'user' => $user,
'mailboxes' => $mailboxes,
'user' => $user,
'mailboxes' => $mailboxes,
'user_mailboxes' => $user->mailboxes,
'users' => $users,
]);
@@ -240,12 +286,27 @@ class UsersController extends Controller
if (!$user->isAdmin()) {
abort(403);
}
$user = User::findOrFail($id);
$user->mailboxes()->sync($request->mailboxes);
$user->mailboxes()->sync($request->mailboxes ?: []);
$user->syncPersonalFolders($request->mailboxes);
// Save permissions.
$user_permissions = $request->user_permissions ?? [];
$permissions = [];
foreach (User::getUserPermissionsList() as $permission_id) {
$new_has_permission = in_array($permission_id, $user_permissions);
if ($user->hasPermission($permission_id, false) != $new_has_permission) {
$permissions[$permission_id] = (int)(bool)$new_has_permission;
$save_user = true;
}
}
$user->permissions = $permissions;
$user->save();
\Session::flash('flash_success_floating', __('Permissions saved successfully'));
return redirect()->route('users.permissions', ['id' => $id]);
@@ -259,6 +320,10 @@ class UsersController extends Controller
$user = User::findOrFail($id);
$this->authorize('update', $user);
if ($user->isDeleted()) {
abort(404);
}
$subscriptions = $user->subscriptions()->select('medium', 'event')->get();
$person = '';
@@ -273,6 +338,7 @@ class UsersController extends Controller
'subscriptions' => $subscriptions,
'person' => $person,
'users' => $users,
'mobile_available' => \Eventy::filter('notifications.mobile_available', false),
]);
}
@@ -311,10 +377,10 @@ class UsersController extends Controller
// Both send and resend
case 'send_invite':
if (!$auth_user->isAdmin()) {
$response['msg'] = __('Not enough permissions');
$response['msg'] = __('Not enough permissions');
}
if (empty($request->user_id)) {
$response['msg'] = __('Incorrect user');
$response['msg'] = __('Incorrect user');
}
if (!$response['msg']) {
$user = User::find($request->user_id);
@@ -331,8 +397,8 @@ class UsersController extends Controller
$response['status'] = 'success';
} catch (\Exception $e) {
// Admin is allowed to see exceptions
$response['msg'] = $e->getMessage();
// Admin is allowed to see exceptions.
$response['msg'] = $e->getMessage().' — '.__('Check mail settings in "Manage » Settings » Mail Settings"');
}
}
break;
@@ -340,10 +406,10 @@ class UsersController extends Controller
// Reset password
case 'reset_password':
if (!auth()->user()->isAdmin()) {
$response['msg'] = __('Not enough permissions');
$response['msg'] = __('Not enough permissions');
}
if (empty($request->user_id)) {
$response['msg'] = __('Incorrect user');
$response['msg'] = __('Incorrect user');
}
if (!$response['msg']) {
$user = User::find($request->user_id);
@@ -368,7 +434,7 @@ class UsersController extends Controller
// Load website notifications
case 'web_notifications':
if (!$auth_user) {
$response['msg'] = __('You are not logged in');
$response['msg'] = __('You are not logged in');
}
if (!$response['msg']) {
$web_notifications_info = $auth_user->getWebsiteNotificationsInfo(false);
@@ -376,8 +442,8 @@ class UsersController extends Controller
'web_notifications_info_data' => $web_notifications_info['data'],
])->render();
$response['has_more_pages'] = (int)$web_notifications_info['notifications']->hasMorePages();
$response['has_more_pages'] = (int) $web_notifications_info['notifications']->hasMorePages();
$response['status'] = 'success';
}
break;
@@ -385,7 +451,7 @@ class UsersController extends Controller
// Mark all user website notifications as read
case 'mark_notifications_as_read':
if (!$auth_user) {
$response['msg'] = __('You are not logged in');
$response['msg'] = __('You are not logged in');
}
if (!$response['msg']) {
$auth_user->unreadNotifications()->update(['read_at' => now()]);
@@ -431,53 +497,10 @@ class UsersController extends Controller
}
if (!$response['msg']) {
event(new UserDeleted($user, $auth_user));
// We have to process conversations one by one to set move them to Unassigned folder,
// as conversations may be in different mailboxes
// $user->conversations()->update(['user_id' => null, 'folder_id' => ]);
$mailbox_unassigned_folders = [];
$user->conversations->each(function ($conversation) {
// We don't fire ConversationUserChanged event to avoid sending notifications to users
$conversation->user_id = null;
$user->deleteUser($auth_user, $request->assign_user);
$folder_id = null;
if (!empty($mailbox_unassigned_folders[$conversation->mailbox_id])) {
$folder_id = $mailbox_unassigned_folders[$conversation->mailbox_id];
} else {
$folder = $conversation->mailbox->folders()
->where('type', Folder::TYPE_UNASSIGNED)
->first();
if ($folder) {
$folder_id = $folder->id;
$mailbox_unassigned_folders[$conversation->mailbox_id] = $folder_id;
}
}
if ($folder_id) {
$conversation->folder_id = $folder_id;
}
$conversation->save();
});
// Recalculate counters for folders
if ($user->isAdmin()) {
// Admin has access to all mailboxes
Mailbox::all()->each(function ($mailbox) {
$mailbox->updateFoldersCounters();
});
} else {
$user->mailboxes->each(function ($mailbox) {
$mailbox->updateFoldersCounters();
});
}
$user->mailboxes()->sync([]);
$user->folders()->delete();
$user->delete();
\Session::flash('flash_success_floating', __('User deleted'));
\Session::flash('flash_success_floating', __('User deleted').': '.$user->getFullName());
$response['status'] = 'success';
}
@@ -489,7 +512,7 @@ class UsersController extends Controller
}
if ($response['status'] == 'error' && empty($response['msg'])) {
$response['msg'] = 'Unknown error occured';
$response['msg'] = 'Unknown error occurred';
}
return \Response::json($response);
@@ -533,7 +556,7 @@ class UsersController extends Controller
// Check current password
if (!Hash::check($request->password_current, $user->password)) {
$validator->errors()->add('password_current', __('This password is incorrect.'));
} else if (Hash::check($request->password, $user->password)) {
} elseif (Hash::check($request->password, $user->password)) {
// Check new password
$validator->errors()->add('password', __('The new password is the same as the old password.'));
}

View File

@@ -33,17 +33,22 @@ class Kernel extends HttpKernel
\App\Http\Middleware\EncryptCookies::class,
\Illuminate\Cookie\Middleware\AddQueuedCookiesToResponse::class,
\Illuminate\Session\Middleware\StartSession::class,
\App\Http\Middleware\TokenAuth::class,
// \Illuminate\Session\Middleware\AuthenticateSession::class,
\Illuminate\View\Middleware\ShareErrorsFromSession::class,
\App\Http\Middleware\VerifyCsrfToken::class,
\Illuminate\Routing\Middleware\SubstituteBindings::class,
\App\Http\Middleware\HttpsRedirect::class,
\App\Http\Middleware\Localize::class,
\App\Http\Middleware\LogoutIfDeleted::class,
\App\Http\Middleware\FrameGuard::class,
\App\Http\Middleware\CustomHandle::class,
],
'api' => [
'throttle:60,1',
'bindings',
],
// 'api' => [
// 'throttle:60,1',
// 'bindings',
// ],
];
/**

View File

@@ -0,0 +1,29 @@
<?php
namespace App\Http\Middleware;
use Closure;
class CustomHandle
{
/**
* Handle an incoming request.
*
* @param \Illuminate\Http\Request $request
* @param \Closure $next
*
* @return mixed
*/
public function handle($request, Closure $next)
{
// Enable/disable chat mode
if ($request->exists('chat_mode')) {
\Helper::setChatMode((int)$request->chat_mode);
}
// Hook.
\Eventy::action('middleware.web.custom_handle', $request);
return \Eventy::filter('middleware.web.custom_handle.response', $next($request), $request, $next);
}
}

View File

@@ -12,6 +12,6 @@ class EncryptCookies extends Middleware
* @var array
*/
protected $except = [
//
'in_app'
];
}

View File

@@ -0,0 +1,32 @@
<?php
namespace App\Http\Middleware;
use Closure;
class FrameGuard
{
/**
* Handle the given request and get the response.
*/
public function handle($request, Closure $next)
{
$response = $next($request);
$x_frame_options = config('app.x_frame_options');
if (false !== $x_frame_options
&& $x_frame_options !== 'false'
&& $x_frame_options !== '0'
) {
$value = 'SAMEORIGIN';
if (is_string($x_frame_options) && preg_match("#(DENY|SAMEORIGIN|ALLOW-FROM)#i", $x_frame_options)) {
$value = $x_frame_options;
}
$response->headers->set('X-Frame-Options', $value, false);
}
return $response;
}
}

View File

@@ -9,17 +9,40 @@ namespace App\Http\Middleware;
use Closure;
use Illuminate\Support\Facades\App;
use Illuminate\Http\Request;
class HttpsRedirect {
/**
* The current proxy header mappings.
*
* @var array
*/
// protected $headers = [
// Request::HEADER_FORWARDED => 'FORWARDED',
// Request::HEADER_X_FORWARDED_FOR => 'X_FORWARDED_FOR',
// Request::HEADER_X_FORWARDED_HOST => 'X_FORWARDED_HOST',
// Request::HEADER_X_FORWARDED_PORT => 'X_FORWARDED_PORT',
// Request::HEADER_X_FORWARDED_PROTO => 'X_FORWARDED_PROTO',
// ];
public function handle($request, Closure $next)
{
if (\Config::get('app.force_https') == 'true') {
$request->setTrustedProxies( [ $request->getClientIp() ] );
if (!$request->secure() /*&& App::environment() === 'production'*/) {
if (\Helper::isHttps()) {
//$request->setTrustedProxies( [ $request->getClientIp() ], array_keys($this->headers));
//!$request->secure()
if (!\Helper::isCurrentUrlHttps()) {
return redirect()->secure($request->getRequestUri());
}
}
// Correct protocol in $_SERVER
if (\Helper::isHttps()
//&& !$request->secure()
&& strtolower($_SERVER['HTTPS'] ?? '') != 'on'
) {
$_SERVER['HTTPS'] = 'on';
}
return $next($request);
}
}

View File

@@ -0,0 +1,29 @@
<?php
namespace App\Http\Middleware;
use Closure;
class Localize
{
/**
* Handle an incoming request.
*
* @param \Illuminate\Http\Request $request
* @param \Closure $next
*
* @return mixed
*/
public function handle($request, Closure $next)
{
// Interface language is set automatically, as locale is stored in .env file.
// Set user language if user logged in.
$user_locale = \Eventy::filter('locale', session('user_locale'));
if ($user_locale) {
\Helper::setLocale($user_locale);
}
return $next($request);
}
}

View File

@@ -0,0 +1,30 @@
<?php
namespace App\Http\Middleware;
use Closure;
use Illuminate\Support\Facades\Auth;
use Illuminate\Support\Facades\Redirect;
class LogoutIfDeleted
{
/**
* Handle an incoming request.
*
* @param \Illuminate\Http\Request $request
* @param \Closure $next
* @param string|null $guard
*
* @return mixed
*/
public function handle($request, Closure $next, $guard = null)
{
$user = Auth::user();
if ($user && ($user->isDeleted() || $user->isDisabled())) {
Auth::logout();
return Redirect::route('login');
}
return $next($request);
}
}

View File

@@ -12,9 +12,9 @@ class ResponseHeaders
// Disable caching
if (method_exists($response, 'header')) {
$response->header('Pragma', 'no-cache');
$response->header('Cache-Control', 'no-cache, max-age=0, must-revalidate, no-store');
}
$response->header('Pragma', 'no-cache');
$response->header('Cache-Control', 'no-cache, max-age=0, must-revalidate, no-store');
}
return $response;
}

View File

@@ -14,7 +14,7 @@ class TerminateHandler
public function terminate($request, $response)
{
// Process events which occured
// Process events which occurred
Subscription::processEvents();
}
}

View File

@@ -0,0 +1,34 @@
<?php
namespace App\Http\Middleware;
use App\User;
use Closure;
class TokenAuth
{
/**
* Handle an incoming request.
*
* @param \Illuminate\Http\Request $request
* @param \Closure $next
*
* @return mixed
*/
public function handle($request, Closure $next)
{
// This is needed to restore authentication when app session expires.
if (!$request->user() && !empty($request->auth_token) && $request->cookie('in_app')) {
try {
$user = User::where(\DB::raw('md5(CONCAT(id, created_at, "'.config('app.key').'"))'), $request->auth_token)
->first();
} catch (\Exception $e) {
\Helper::logException($e, '[TokenAuth]');
}
if (!empty($user)) {
\Auth::login($user);
}
}
return $next($request);
}
}

View File

@@ -2,12 +2,57 @@
namespace App;
use App\Thread;
use Illuminate\Database\Eloquent\Model;
class Job extends Model
{
const UPDATED_AT = null;
public $payload_decoded = null;
/**
* Automatically converted into Carbon dates.
*/
protected $dates = ['created_at', 'available_at', 'reserved_at'];
public function getPayloadDecoded()
{
if ($this->payload_decoded !== null) {
return $this->payload_decoded;
}
$this->payload_decoded = json_decode($this->payload, true);
return $this->payload_decoded;
}
public function getCommand()
{
return self::getPayloadCommand($this->getPayloadDecoded());
}
public function getCommandLastThread()
{
$command = $this->getCommand();
if ($command && !empty($command->threads)) {
return Thread::getLastThread($command->threads);
}
return null;
}
public static function getPayloadCommand($payload)
{
if (empty($payload['data']) || empty($payload['data']['command'])) {
return null;
}
try {
// If some record has been deleted from DB, there will be an error:
// No query results for model [App\Conversation].
return unserialize($payload['data']['command']);
} catch (\Exception $e) {
return null;
}
}
}

View File

@@ -0,0 +1,41 @@
<?php
/**
* Used to stop current queue:work in order to start a new one.
* https://github.com/freescout-helpdesk/freescout/issues/2507#issuecomment-1376006247
*/
namespace App\Jobs;
use Illuminate\Bus\Queueable;
use Illuminate\Contracts\Queue\ShouldQueue;
use Illuminate\Foundation\Bus\Dispatchable;
use Illuminate\Queue\InteractsWithQueue;
use Illuminate\Queue\SerializesModels;
class RestartQueueWorker implements ShouldQueue
{
use Dispatchable, InteractsWithQueue, Queueable, SerializesModels;
/**
* Create a new job instance.
*
* @return void
*/
public function __construct()
{
}
/**
* Execute the job.
*
* @return void
*/
public function handle()
{
$this->delete();
// register_shutdown_function() is called on exit(),
// so commands mutexes are removed.
exit();
}
}

View File

@@ -2,11 +2,12 @@
/**
* Send alert to super admin.
*/
namespace App\Jobs;
use App\Mail\Alert;
use App\SendLog;
use App\User;
use App\Mail\Alert;
use Illuminate\Bus\Queueable;
use Illuminate\Contracts\Queue\ShouldQueue;
use Illuminate\Foundation\Bus\Dispatchable;
@@ -19,8 +20,17 @@ class SendAlert implements ShouldQueue
use Dispatchable, InteractsWithQueue, Queueable, SerializesModels;
public $text;
public $title;
/**
* The number of seconds the job can run before timing out.
* fwrite() function in /vendor/swiftmailer/swiftmailer/lib/classes/Swift/Transport/StreamBuffer.php
* in some cases may stuck and continue infinitely. This blocks queue:work and no other jobs are processed.
* So we need to set the timeout. On timeout the whole queue:work process is being killed by Laravel.
*/
public $timeout = 120;
/**
* Create a new job instance.
*
@@ -41,19 +51,18 @@ class SendAlert implements ShouldQueue
{
// Configure mail driver according to Mailbox settings
\MailHelper::setSystemMailDriver();
$recipients = [];
$super_admin = User::getSuperAdmin();
if ($super_admin) {
$recipients[] = $super_admin->email;
}
$recipients = User::nonDeleted()
->where('role', User::ROLE_ADMIN)
->where('invite_state', User::INVITE_STATE_ACTIVATED)
->pluck('email')
->toArray();
$extra = \MailHelper::sanitizeEmails(\Option::get('alert_recipients'));
if ($extra) {
$recipients = array_unique(array_merge($recipients, $extra));
}
foreach ($recipients as $recipient) {
$exception = null;

View File

@@ -23,6 +23,14 @@ class SendAutoReply implements ShouldQueue
public $customer;
/**
* The number of seconds the job can run before timing out.
* fwrite() function in /vendor/swiftmailer/swiftmailer/lib/classes/Swift/Transport/StreamBuffer.php
* in some cases may stuck and continue infinitely. This blocks queue:work and no other jobs are processed.
* So we need to set the timeout. On timeout the whole queue:work process is being killed by Laravel.
*/
public $timeout = 120;
/**
* Create a new job instance.
*
@@ -43,22 +51,32 @@ class SendAutoReply implements ShouldQueue
*/
public function handle()
{
// Auto reply disabled.
if (!empty($this->conversation->meta['ar_off'])) {
return;
}
// Configure mail driver according to Mailbox settings
\App\Misc\Mail::setMailDriver($this->mailbox);
\App\Misc\Mail::setMailDriver($this->mailbox, null, $this->conversation);
// Auto reply appears as reply in customer's mailbox
$headers['In-Reply-To'] = '<'.$this->thread->message_id.'>';
$headers['References'] = '<'.$this->thread->message_id.'>';
// Create Message-ID for the auto reply
$message_id = \App\Misc\Mail::MESSAGE_ID_PREFIX_AUTO_REPLY.'-'.$this->thread->id.'-'.md5($this->thread->id).'@'.$this->mailbox->getEmailDomain();
$message_id = \App\Misc\Mail::MESSAGE_ID_PREFIX_AUTO_REPLY.'-'.$this->thread->id.'-'.\MailHelper::getMessageIdHash($this->thread->id).'@'.$this->mailbox->getEmailDomain();
$headers['Message-ID'] = $message_id;
$customer_email = $this->conversation->customer_email;
if (!$customer_email) {
// When message is received via Chat, customer has no email adddress.
return;
}
$recipients = [$customer_email];
$failures = [];
$exception = null;
$failures = [];
$exception = null;
try {
Mail::to([['name' => $this->customer->getFullName(), 'email' => $customer_email]])
->send(new AutoReply($this->conversation, $this->mailbox, $this->customer, $headers));

View File

@@ -7,7 +7,6 @@ namespace App\Jobs;
use App\Mail\UserEmailReplyError;
use App\SendLog;
use App\Thread;
use Illuminate\Bus\Queueable;
use Illuminate\Contracts\Queue\ShouldQueue;
use Illuminate\Foundation\Bus\Dispatchable;
@@ -25,6 +24,14 @@ class SendEmailReplyError implements ShouldQueue
public $mailbox;
/**
* The number of seconds the job can run before timing out.
* fwrite() function in /vendor/swiftmailer/swiftmailer/lib/classes/Swift/Transport/StreamBuffer.php
* in some cases may stuck and continue infinitely. This blocks queue:work and no other jobs are processed.
* So we need to set the timeout. On timeout the whole queue:work process is being killed by Laravel.
*/
public $timeout = 120;
/**
* Create a new job instance.
*
@@ -48,6 +55,7 @@ class SendEmailReplyError implements ShouldQueue
\App\Misc\Mail::setMailDriver($this->mailbox);
$exception = null;
try {
Mail::to([['name' => '', 'email' => $this->from]])
->send(new UserEmailReplyError());

View File

@@ -22,6 +22,17 @@ class SendNotificationToUsers implements ShouldQueue
public $threads;
// Max retries + 1
public $tries = 168; // One per hour
/**
* The number of seconds the job can run before timing out.
* fwrite() function in /vendor/swiftmailer/swiftmailer/lib/classes/Swift/Transport/StreamBuffer.php
* in some cases may stuck and continue infinitely. This blocks queue:work and no other jobs are processed.
* So we need to set the timeout. On timeout the whole queue:work process is being killed by Laravel.
*/
public $timeout = 120;
/**
* Create a new job instance.
*
@@ -44,46 +55,92 @@ class SendNotificationToUsers implements ShouldQueue
$mailbox = $this->conversation->mailbox;
// Configure mail driver according to Mailbox settings
\App\Misc\Mail::setMailDriver($mailbox);
\App\Misc\Mail::setMailDriver($mailbox, null, $this->conversation);
// Threads has to be sorted here, if sorted before, they come here in wrong order
$this->threads = $this->threads->sortByDesc(function ($item, $key) {
return $item->created_at;
});
$this->threads = Thread::sortThreads($this->threads);
$headers = [];
$last_thread = $this->threads->first();
if (!$last_thread) {
return;
}
// If thread is draft, it means it has been undone
if ($last_thread->isDraft()) {
return;
}
// Limit conversation history
if (config('app.email_user_history') == 'last') {
$this->threads = $this->threads->slice(0, 2);
}
if (config('app.email_user_history') == 'none') {
$this->threads = $this->threads->slice(0, 1);
}
// All notification for the same conversation has same dummy Message-ID
$prev_message_id = \App\Misc\Mail::MESSAGE_ID_PREFIX_NOTIFICATION_IN_REPLY.'-'.$this->conversation->id.'-'.md5($this->conversation->id).'@'.$mailbox->getEmailDomain();
$headers['In-Reply-To'] = '<'.$prev_message_id.'>';
$headers['References'] = '<'.$prev_message_id.'>';
// https://github.com/freescout-helpdesk/freescout/issues/2488
$headers['X-Auto-Response-Suppress'] = 'All';
// We throw an exception if any of the send attempts throws an exception (connection error, etc)
$global_exception = null;
foreach ($this->users as $user) {
// User can ne deleted from DB.
if (!isset($user->id)) {
continue;
}
if ($user->isDeleted()) {
continue;
}
// If for one user sending fails the job is marked as failed and retried after some time.
// So we have to check if notification email has already been successfully sent to this user.
if ($this->attempts() > 1) {
// Maybe add indexes to the table.
$already_sent = SendLog::where('thread_id', $last_thread->id)
->where('mail_type', SendLog::MAIL_TYPE_USER_NOTIFICATION)
->where('user_id', $user->id)
->whereIn('status', SendLog::$sent_success)
->exists();
if ($already_sent) {
continue;
}
}
$message_id = \App\Misc\Mail::MESSAGE_ID_PREFIX_NOTIFICATION.'-'.$last_thread->id.'-'.$user->id.'-'.time().'@'.$mailbox->getEmailDomain();
$headers['Message-ID'] = $message_id;
// If this is notification on message from customer set customer as sender name
// If this is notification on message from customer, set customer as sender name
$from_name = '';
if ($last_thread->type == Thread::TYPE_CUSTOMER) {
$from_name = $last_thread->customer->getFullName();
$from_name = '';
if ($last_thread->customer) {
$from_name = $last_thread->customer->getFullName(true, true);
}
if ($from_name) {
$from_name = $from_name.' '.__('via').' '.\Config::get('app.name');
$from_name = $from_name.' '.__('via').' '.$mailbox->name;
}
}
if (!$from_name) {
$from_name = \Config::get('app.name');
$from_name = $mailbox->name;
}
$from = ['address' => $mailbox->email, 'name' => $from_name];
// Set user language
app()->setLocale($user->getLocale());
$headers['X-FreeScout-Mail-Type'] = 'user.notification';
$headers = \Eventy::filter('jobs.send_reply_to_customer.headers', $headers, $user, $mailbox, $this->conversation, $this->threads, $from);
$exception = null;
try {
@@ -122,7 +179,24 @@ class SendNotificationToUsers implements ShouldQueue
}
if ($global_exception) {
throw $global_exception;
// Retry job with delay.
// https://stackoverflow.com/questions/35258175/how-can-i-create-delays-between-failed-queued-job-attempts-in-laravel
// We do not try to resend Bounce messages: https://github.com/freescout-helpdesk/freescout/issues/3156
if ($this->attempts() < $this->tries && !$last_thread->isBounce()) {
if ($this->attempts() == 1) {
// Second attempt after 5 min.
$this->release(300);
} else {
// Others - after 1 hour.
$this->release(3600);
}
throw $global_exception;
} else {
$this->fail($global_exception);
return;
}
}
}

View File

@@ -3,14 +3,17 @@
namespace App\Jobs;
use App\Mail\ReplyToCustomer;
use App\Customer;
use App\SendLog;
use App\Thread;
use App\Misc\SwiftGetSmtpQueueId;
use Illuminate\Bus\Queueable;
use Illuminate\Contracts\Queue\ShouldQueue;
use Illuminate\Foundation\Bus\Dispatchable;
use Illuminate\Queue\InteractsWithQueue;
use Illuminate\Queue\SerializesModels;
use Mail;
//use Webklex\IMAP\Client;
class SendReplyToCustomer implements ShouldQueue
{
@@ -28,6 +31,17 @@ class SendReplyToCustomer implements ShouldQueue
private $message_id = '';
private $customer_email = '';
// Number of retries + 1
public $tries = 168; // one per hour
/**
* The number of seconds the job can run before timing out.
* fwrite() function in /vendor/swiftmailer/swiftmailer/lib/classes/Swift/Transport/StreamBuffer.php
* in some cases may stuck and continue infinitely. This blocks queue:work and no other jobs are processed.
* So we need to set the timeout. On timeout the whole queue:work process is being killed by Laravel.
*/
public $timeout = 120;
/**
* Create a new job instance.
*
@@ -47,47 +61,183 @@ class SendReplyToCustomer implements ShouldQueue
*/
public function handle()
{
$send_previous_messages = false;
$is_forward = false;
// When forwarding conversation is undone, new conversation is deleted.
if (!$this->conversation) {
return;
}
$mailbox = $this->conversation->mailbox;
// Mailbox may be deleted.
if (!$mailbox) {
return;
}
// Add forwarded conversation replies.
if ($this->conversation->threads_count == 1 && count($this->threads) == 1) {
$forward_child_thread = $this->threads[0];
if ($forward_child_thread->isForwarded() && $forward_child_thread->getForwardParentConversation()) {
// Add replies from original conversation.
$forwarded_replies = $forward_child_thread->getForwardParentConversation()->getReplies();
$forwarded_replies = Thread::sortThreads($forwarded_replies);
$forward_parent_thread = Thread::find($forward_child_thread->getMetaFw(Thread::META_FORWARD_PARENT_THREAD_ID));
if ($forward_parent_thread) {
// Remove threads created after forwarding.
foreach ($forwarded_replies as $i => $thread) {
if ($thread->created_at > $forward_parent_thread->created_at) {
$forwarded_replies->forget($i);
}
}
$this->threads = $this->threads->merge($forwarded_replies);
$is_forward = true;
}
}
}
// Threads has to be sorted here, if sorted before, they come here in wrong order
$this->threads = $this->threads->sortByDesc(function ($item, $key) {
return $item->created_at;
});
$this->threads = Thread::sortThreads($this->threads);
$new = false;
$headers = [];
$this->last_thread = $this->threads->first();
$prev_thread = null;
if ($this->last_thread === null) {
return;
}
$last_customer_thread = null;
// If thread is draft, it means it has been undone
if ($this->last_thread->isDraft()) {
return;
}
// Configure mail driver according to Mailbox settings
\App\Misc\Mail::setMailDriver($mailbox, $this->last_thread->created_by_user);
// After sending an email we are saving it into "IMAP Folder To Save Outgoing Replies".
// This process may stuck or make SendReplyToCustomer job die with
// "Allowed memory size of NNN bytes exhausted" error.
// https://github.com/freescout-helpdesk/freescout/issues/3632
if ($this->attempts() >= 1 &&
($this->last_thread->send_status == SendLog::STATUS_ACCEPTED
|| $this->last_thread->isSendStatusSuccess())
) {
return;
}
if (count($this->threads) == 1) {
$new = true;
}
$i = 0;
foreach ($this->threads as $thread) {
if ($i == 1) {
$prev_thread = $thread;
break;
if (!$new) {
$i = 0;
foreach ($this->threads as $thread) {
if ($i > 0 && $thread->type == Thread::TYPE_CUSTOMER) {
$last_customer_thread = $thread;
break;
}
$i++;
}
$i++;
}
// Get penultimate email Message-Id if reply
if (!$new && !empty($prev_thread) && $prev_thread->message_id) {
$headers['In-Reply-To'] = '<'.$prev_thread->message_id.'>';
$headers['References'] = '<'.$prev_thread->message_id.'>';
// In-Reply-To and References headers.
$references = '';
if (!$new && !empty($last_customer_thread) && $last_customer_thread->message_id) {
$headers['In-Reply-To'] = '<'.$last_customer_thread->message_id.'>';
//$headers['References'] = '<'.$last_customer_thread->message_id.'>';
// https://github.com/freescout-helpdesk/freescout/issues/3175
$i = 0;
$references_array = [];
foreach ($this->threads as $thread) {
if ($i > 0) {
$reference = $thread->getMessageId();
if ($reference) {
$references_array[] = $reference;
}
}
$i++;
}
if ($references_array) {
$references = '<'.implode('> <', array_reverse($references_array)).'>';
}
if ($references) {
$headers['References'] = $references;
}
}
$this->message_id = \App\Misc\Mail::MESSAGE_ID_PREFIX_REPLY_TO_CUSTOMER.'-'.$this->last_thread->id.'-'.md5($this->last_thread->id).'@'.$mailbox->getEmailDomain();
// Conversation history.
$email_conv_history = config('app.email_conv_history');
$threads_count = count($this->threads);
$meta_conv_history = $this->last_thread->getMeta(Thread::META_CONVERSATION_HISTORY);
if (!empty($meta_conv_history)) {
$email_conv_history = $meta_conv_history;
}
if ($is_forward && $email_conv_history == 'global') {
$email_conv_history = 'full';
}
if ($is_forward && $email_conv_history == 'none') {
$email_conv_history = 'full';
}
if ($email_conv_history == 'full') {
$send_previous_messages = true;
}
if ($email_conv_history == 'last') {
$send_previous_messages = true;
$this->threads = $this->threads->slice(0, 2);
}
if ($email_conv_history == 'none') {
$send_previous_messages = false;
}
if (!$is_forward) {
$send_previous_messages = \Eventy::filter('jobs.send_reply_to_customer.send_previous_messages', $send_previous_messages, $this->last_thread, $this->threads, $this->conversation, $this->customer);
}
// Remove previous messages.
if (!$send_previous_messages) {
$this->threads = $this->threads->slice(0, 1);
}
// Configure mail driver according to Mailbox settings
\MailHelper::setMailDriver($mailbox, $this->last_thread->created_by_user, $this->conversation);
// https://github.com/freescout-helpdesk/freescout/issues/3330
if (!\MailHelper::$smtp_queue_id_plugin_registered) {
\Mail::getSwiftMailer()->registerPlugin(new SwiftGetSmtpQueueId());
\MailHelper::$smtp_queue_id_plugin_registered = true;
}
$this->message_id = $this->last_thread->getMessageId($mailbox);
$headers['Message-ID'] = $this->message_id;
$this->customer_email = $this->conversation->customer_email;
// For phone conversations we may need to get customer email.
// https://github.com/freescout-helpdesk/freescout/issues/3270
if (!$this->customer_email && $this->conversation->isPhone()) {
$this->customer_email = $this->conversation->customer->getMainEmail();
if (!$this->customer_email) {
return;
}
}
// Try to get customer by email
if (!$this->customer) {
$this->customer = Customer::getByEmail($this->customer_email);
return;
}
$to_array = $mailbox->removeMailboxEmailsFromList($this->last_thread->getToArray());
$cc_array = $mailbox->removeMailboxEmailsFromList($this->last_thread->getCcArray());
$bcc_array = $mailbox->removeMailboxEmailsFromList($this->last_thread->getBccArray());
@@ -95,35 +245,257 @@ class SendReplyToCustomer implements ShouldQueue
$cc_array = \App\Misc\Mail::removeEmailFromArray($cc_array, $this->customer_email);
$bcc_array = \App\Misc\Mail::removeEmailFromArray($bcc_array, $this->customer_email);
// Auto Bcc.
if ($mailbox->auto_bcc) {
$auto_bcc = \MailHelper::sanitizeEmails($mailbox->auto_bcc);
if ($auto_bcc) {
$bcc_array = array_merge($bcc_array, $auto_bcc);
}
}
// Remove from BCC emails which are present in CC
foreach ($cc_array as $cc_email) {
$bcc_array = \App\Misc\Mail::removeEmailFromArray($bcc_array, $cc_email);
}
$this->recipients = array_merge([$this->customer_email], $cc_array, $bcc_array);
$this->recipients = array_merge($to_array, $cc_array, $bcc_array);
$to = [];
if (count($to_array) > 1) {
$to = $to_array;
} else {
$to = [['name' => $this->customer->getFullName(), 'email' => $this->customer_email]];
}
// If sending fails, all recipiens fail.
// if ($this->attempts() > 1) {
// $cc_array = [];
// $bcc_array = [];
// }
$subject = $this->conversation->subject;
if (!$new && !$is_forward) {
$subject = 'Re: '.$subject;
}
$subject = \Eventy::filter('email.reply_to_customer.subject', $subject, $this->conversation, $this->last_thread);
$this->threads = \Eventy::filter('email.reply_to_customer.threads', $this->threads, $this->conversation, $mailbox);
$headers['X-FreeScout-Mail-Type'] = 'customer.message';
$reply_mail = new ReplyToCustomer($this->conversation, $this->threads, $headers, $mailbox, $subject, $threads_count);
$smtp_queue_id = null;
try {
Mail::to([['name' => $this->customer->getFullName(), 'email' => $this->customer_email]])
Mail::to($to)
->cc($cc_array)
->bcc($bcc_array)
->send(new ReplyToCustomer($this->conversation, $this->threads, $headers, $mailbox));
->send($reply_mail);
$this->last_thread->send_status = SendLog::STATUS_ACCEPTED;
$this->last_thread->save();
$smtp_queue_id = SwiftGetSmtpQueueId::$last_smtp_queue_id;
} catch (\Exception $e) {
// We come here in case SMTP server unavailable for example
activity()
->causedBy($this->customer)
->withProperties([
'error' => $e->getMessage().'; File: '.$e->getFile().' ('.$e->getLine().')',
])
->useLog(\App\ActivityLog::NAME_EMAILS_SENDING)
->log(\App\ActivityLog::DESCRIPTION_EMAILS_SENDING_ERROR_TO_CUSTOMER);
if ($this->attempts() == 1) {
activity()
->causedBy($this->customer)
->withProperties([
'error' => $e->getMessage().'; File: '.$e->getFile().' ('.$e->getLine().')',
])
->useLog(\App\ActivityLog::NAME_EMAILS_SENDING)
->log(\App\ActivityLog::DESCRIPTION_EMAILS_SENDING_ERROR_TO_CUSTOMER);
}
// Failures will be saved to send log when retry attempts will finish
// Mail::failures() is empty in case of connection error.
$this->failures = $this->recipients;
// Save to send log
$this->saveToSendLog($e->getMessage());
// Save to send log (only first attempt).
if ($this->attempts() == 1) {
$this->saveToSendLog($e->getMessage());
}
throw $e;
$error_message = $e->getMessage();
// Remove stack trace from error message.
$error_message = preg_replace('#[\r\n]*" in /.*#s', '"', $error_message);
// SMTP response code is stored in the exception message:
// Expected response code 235 but got code "535", with message...
preg_match('#but got code "(\d+)",#', $error_message, $response_m);
$response_code = (int)($response_m[1] ?? 0);
// Retry job with delay.
// https://stackoverflow.com/questions/35258175/how-can-i-create-delays-between-failed-queued-job-attempts-in-laravel
if ($this->attempts() < $this->tries && !preg_match("/".config("app.no_retry_mail_errors")."/i", $error_message)) {
if ($this->attempts() == 1) {
// Second attempt after 5 min.
$this->release(300);
} else {
// Others - after 1 hour.
$this->release(3600);
}
// If an email has not been sent after 1 hour - show an error message to support agent.
if ($this->attempts() >= 3 || $response_code >= 500) {
$this->last_thread->send_status = SendLog::STATUS_SEND_INTERMEDIATE_ERROR;
$this->last_thread->updateSendStatusData(['msg' => $error_message]);
$this->last_thread->save();
}
throw $e;
} else {
$this->last_thread->send_status = SendLog::STATUS_SEND_ERROR;
$this->last_thread->updateSendStatusData(['msg' => $error_message]);
$this->last_thread->save();
// This executes $this->failed().
$this->fail($e);
return;
}
}
SwiftGetSmtpQueueId::$last_smtp_queue_id = null;
// Clean error message if email finally has been sent.
if ($this->last_thread->send_status == SendLog::STATUS_SEND_ERROR) {
$this->last_thread->send_status = null;
$this->last_thread->updateSendStatusData(['msg' => '']);
$this->last_thread->save();
}
$imap_sent_folder = $mailbox->imap_sent_folder;
if ($imap_sent_folder) {
try {
$client = \MailHelper::getMailboxClient($mailbox);
$client->connect();
$mail_from = $mailbox->getMailFrom($this->last_thread->created_by_user ?? null, $this->conversation);
if (!empty($mail_from['name'])) {
$envelope['from'] = '"'.$mail_from['name'].'" <'.$mail_from['address'].'>';
} else {
$envelope['from'] = $mail_from['address'];
}
if (is_array($to) && !empty($to[0]) && !empty($to[0]['name']) && !empty($to[0]['email'])) {
$envelope['to'] = '"'.$to[0]['name'].'" <'.$to[0]['email'].'>';
} else {
$envelope['to'] = $this->customer_email;
}
$envelope['subject'] = $subject;
$envelope['date'] = now()->toRfc2822String();
$envelope['message_id'] = $this->message_id;
// CC.
if (count($cc_array)) {
$envelope['cc'] = implode(',', $cc_array);
}
// Get penultimate email Message-Id if reply
if (!$new && !empty($last_customer_thread) && $last_customer_thread->message_id) {
$envelope['custom_headers'] = [
'In-Reply-To: <'.$last_customer_thread->message_id.'>',
'References: '.$references,
];
}
// Remove new lines to avoid "imap_mail_compose(): header injection attempt in subject".
foreach ($envelope as $i => $envelope_value) {
$envelope[$i] = preg_replace("/[\r\n]/", '', $envelope_value);
}
$parts = [];
// Multipart flag.
if ($this->last_thread->has_attachments) {
$multipart = [];
$multipart["type"] = TYPEMULTIPART;
$multipart["subtype"] = "mixed";
// https://github.com/freescout-helpdesk/freescout/issues/3934
//$multipart["subtype"] = "alternative";
$parts[] = $multipart;
}
// Body.
$part_body['type'] = TYPETEXT;
$part_body['subtype'] = 'html';
$part_body['contents.data'] = $reply_mail->render();
$part_body['charset'] = 'utf-8';
$parts[] = $part_body;
// Add attachments.
if ($this->last_thread->has_attachments) {
foreach ($this->last_thread->attachments as $attachment) {
if ($attachment->embedded) {
continue;
}
if ($attachment->fileExists()) {
$part = [];
$part["type"] = 'APPLICATION';
$part["encoding"] = ENCBASE64;
$part["subtype"] = "octet-stream";
$part["description"] = $attachment->file_name;
$part['disposition.type'] = 'attachment';
$part['disposition'] = array('filename' => $attachment->file_name);
$part['type.parameters'] = array('name' => $attachment->file_name);
$part["description"] = '';
$part["contents.data"] = base64_encode($attachment->getFileContents());
$parts[] = $part;
} else {
\Log::error('[IMAP Folder To Save Outgoing Replies] Thread: '.$this->last_thread->id.'. Attachment file not find on disk: '.$attachment->getLocalFilePath());
}
}
}
try {
// https://github.com/freescout-helpdesk/freescout/issues/3502
$imap_sent_folder = mb_convert_encoding($imap_sent_folder, "UTF7-IMAP","UTF-8");
// https://github.com/Webklex/php-imap/issues/380
if (method_exists($client, 'getFolderByPath')) {
$folder = $client->getFolderByPath($imap_sent_folder);
} else {
$folder = $client->getFolder($imap_sent_folder);
}
// Get folder method does not work if sent folder has spaces.
if ($folder) {
try {
$save_result = $this->saveEmailToFolder($client, $folder, $envelope, $parts, $bcc_array);
// Sometimes emails with attachments by some reason are not saved.
// https://github.com/freescout-helpdesk/freescout/issues/2749
if (!$save_result) {
// Save without attachments.
$save_result = $this->saveEmailToFolder($client, $folder, $envelope, [$part_body], $bcc_array);
if (!$save_result) {
\Log::error($this->getImapSaveErrorPrefix($mailbox).'Could not save outgoing reply to the IMAP folder (check folder name and make sure IMAP folder does not have spaces - folders with spaces do not work): '.$imap_sent_folder);
}
}
} catch (\Exception $e) {
// Just log error and continue.
\Helper::logException($e, $this->getImapSaveErrorPrefix($mailbox).'Could not save outgoing reply to the IMAP folder: ');
}
} else {
\Log::error($this->getImapSaveErrorPrefix($mailbox).'Could not save outgoing reply to the IMAP folder (check folder name and make sure IMAP folder does not have spaces - folders with spaces do not work): '.$imap_sent_folder);
}
} catch (\Exception $e) {
// Just log error and continue.
\Helper::logException($e, $this->getImapSaveErrorPrefix($mailbox).'Could not save outgoing reply to the IMAP folder, IMAP folder not found: '.$imap_sent_folder.' - ');
//$this->saveToSendLog('['.date('Y-m-d H:i:s').'] Could not save outgoing reply to the IMAP folder: '.$imap_sent_folder);
}
} catch (\Exception $e) {
// Just log error and continue.
//$this->saveToSendLog('['.date('Y-m-d H:i:s').'] Could not get mailbox IMAP folder: '.$imap_sent_folder);
\Helper::logException($e, $this->getImapSaveErrorPrefix($mailbox).'Could not save outgoing reply to the IMAP folder: '.$imap_sent_folder.' - ');
}
}
// In message_id we are storing Message-ID of the incoming email which created the thread
@@ -135,7 +507,35 @@ class SendReplyToCustomer implements ShouldQueue
$this->failures = Mail::failures();
// Save to send log
$this->saveToSendLog();
$this->saveToSendLog('', $smtp_queue_id);
}
public function getImapSaveErrorPrefix($mailbox)
{
return '['.$mailbox->name.' » Connection Settings » Fetching Emails » IMAP Folder To Save Outgoing Replies] ';
}
// Save an email to IMAP folder.
public function saveEmailToFolder($client, $folder, $envelope, $parts, $bcc = [])
{
$envelope_str = imap_mail_compose($envelope, $parts);
// Add BCC.
// https://stackoverflow.com/questions/47353938/php-imap-append-with-bcc
if (!empty($bcc)) {
// There will be a "To:" parameter for sure.
$to_pos = strpos($envelope_str , "To:");
if ($to_pos !== false) {
$bcc_str = "Bcc: " . implode(',', $bcc) . "\r\n";
$envelope_str = substr_replace($envelope_str , $bcc_str, $to_pos, 0);
}
}
if (get_class($client) == 'Webklex\PHPIMAP\Client') {
return $folder->appendMessage($envelope_str, ['\Seen'], now()->format('d-M-Y H:i:s O'));
} else {
return $folder->appendMessage($envelope_str, '\Seen', now()->format('d-M-Y H:i:s O'));
}
}
/**
@@ -164,7 +564,7 @@ class SendReplyToCustomer implements ShouldQueue
/**
* Save emails to send log.
*/
public function saveToSendLog($error_message = '')
public function saveToSendLog($error_message = '', $smtp_queue_id = '')
{
foreach ($this->recipients as $recipient) {
if (in_array($recipient, $this->failures)) {
@@ -179,7 +579,7 @@ class SendReplyToCustomer implements ShouldQueue
} else {
$customer_id = null;
}
SendLog::log($this->last_thread->id, $this->message_id, $recipient, SendLog::MAIL_TYPE_EMAIL_TO_CUSTOMER, $status, $customer_id, null, $status_message);
SendLog::log($this->last_thread->id, $this->message_id, $recipient, SendLog::MAIL_TYPE_EMAIL_TO_CUSTOMER, $status, $customer_id, null, $status_message, $smtp_queue_id);
}
}
}

View File

@@ -0,0 +1,44 @@
<?php
/**
* Used to tirgger Eventy actions with delay.
*/
namespace App\Jobs;
use Illuminate\Bus\Queueable;
use Illuminate\Contracts\Queue\ShouldQueue;
use Illuminate\Foundation\Bus\Dispatchable;
use Illuminate\Queue\InteractsWithQueue;
use Illuminate\Queue\SerializesModels;
class TriggerAction implements ShouldQueue
{
use Dispatchable, InteractsWithQueue, Queueable, SerializesModels;
public $action;
public $params;
/**
* Create a new job instance.
*
* @return void
*/
public function __construct($action, $params)
{
$this->action = $action;
$this->params = $params;
}
/**
* Execute the job.
*
* @return void
*/
public function handle()
{
$args = $this->params;
array_unshift($args, $this->action);
call_user_func_array("\Eventy::action", $args);
}
}

View File

@@ -0,0 +1,46 @@
<?php
namespace App\Jobs;
use App\Folder;
use Illuminate\Support\Facades\Cache;
use Illuminate\Bus\Queueable;
use Illuminate\Queue\SerializesModels;
use Illuminate\Queue\InteractsWithQueue;
use Illuminate\Contracts\Queue\ShouldQueue;
use Illuminate\Foundation\Bus\Dispatchable;
class UpdateFolderCounters implements ShouldQueue
{
use Dispatchable, InteractsWithQueue, Queueable, SerializesModels;
private $folder;
// Cache lock key
private $lockKey;
public function __construct(Folder $folder)
{
$this->folder = $folder;
$this->lockKey = "folder_update_lock_{$folder->id}";
}
public function handle()
{
// Check if another job is processing this folder
if (Cache::has($this->lockKey)) {
return; // Exit if already processing
}
// Set lock with a timeout of 5 minutes (adjust as needed)
Cache::put($this->lockKey, true, now()->addMinutes(5));
try {
// Perform the folder update logic
$this->folder->updateCountersNow();
} finally {
// Release the lock after processing
Cache::forget($this->lockKey);
}
}
}

View File

@@ -26,8 +26,8 @@ class LogLockout
public function handle(Lockout $event)
{
activity()
->causedBy($event->user)
->withProperties(['ip' => app('request')->ip()])
//->causedBy($event->user)
->withProperties(['ip' => app('request')->ip(), 'email' => $event->request->email])
->useLog(\App\ActivityLog::NAME_USER)
->log(\App\ActivityLog::DESCRIPTION_USER_LOCKED);
}

View File

@@ -26,7 +26,7 @@ class LogUserDeletion
public function handle(UserDeleted $event)
{
activity()
->causedBy($event->user)
->causedBy($event->by_user)
->withProperties(['deleted_user' => $event->deleted_user->getFullName().' ['.$event->deleted_user->id.']'])
->useLog(\App\ActivityLog::NAME_USER)
->log(\App\ActivityLog::DESCRIPTION_USER_DELETED);

View File

@@ -0,0 +1,25 @@
<?php
namespace App\Listeners;
class ProcessSwiftMessage
{
/**
* Create the event listener.
*
* @return void
*/
public function __construct()
{
//
}
/**
* Handle the event.
*/
public function handle($event)
{
return \Eventy::filter('mail.process_swift_message', true, $event->message);
}
}

View File

@@ -0,0 +1,30 @@
<?php
namespace App\Listeners;
use App\Conversation;
class RefreshConversations
{
/**
* Create the event listener.
*
* @return void
*/
public function __construct()
{
//
}
/**
* Handle the event.
*
* @param $event
*
* @return void
*/
public function handle($event)
{
Conversation::refreshConversations($event->conversation, $event->thread ?? $event->last_thread);
}
}

View File

@@ -0,0 +1,31 @@
<?php
namespace App\Listeners;
use Illuminate\Auth\Events\Login;
class RememberUserLocale
{
/**
* Create the event listener.
*
* @return void
*/
public function __construct()
{
//
}
/**
* Handle the event.
*
* @param Login $event
*
* @return void
*/
public function handle(Login $event)
{
// Save user locale to session to show user app in his chosen language.
session()->put('user_locale', $event->user->getLocale());
}
}

View File

@@ -0,0 +1,30 @@
<?php
namespace App\Listeners;
class RestartSwiftMailer
{
/**
* Create the event listener.
*
* @return void
*/
public function __construct()
{
//
}
/**
* Handle the event.
*/
public function handle($event)
{
// Destroy Swift mailer to make it clean temp files.
// https://github.com/freescout-helpdesk/freescout/issues/2949
// https://github.com/swiftmailer/swiftmailer/issues/1287#issuecomment-833505298
\App::forgetInstance('mailer');
\App::forgetInstance('swift.mailer');
\App::forgetInstance('swift.transport');
}
}

View File

@@ -2,10 +2,14 @@
namespace App\Listeners;
use App\Conversation;
use App\Mailbox;
use App\SendLog;
class SendAutoReply
{
const CHECK_PERIOD = 180; // min
/**
* Create the event listener.
*
@@ -23,7 +27,67 @@ class SendAutoReply
{
$conversation = $event->conversation;
if (/*!$conversation->imported &&*/ $conversation->mailbox->auto_reply_enabled) {
// no_autoreply meta value is checked in the SendAutoReply job.
if (!$conversation->imported
&& $conversation->mailbox->auto_reply_enabled
) {
$thread = $conversation->threads()->first();
// Do not send auto reply to auto responders.
if ($thread->isAutoResponder()) {
return;
}
// Do not send auto replies to bounces.
if ($thread->isBounce()) {
return;
}
// Do not send auto replies to spam messages.
if ($conversation->status == Conversation::STATUS_SPAM) {
return;
}
if (!\Eventy::filter('autoreply.should_send', true, $conversation)) {
return;
}
// We can not send auto reply to incoming bounce messages, as it will lead to the infinite loop:
// application will be sending auto replies and mail server will be sending bounce messages to auto replies.
// Bounce detection can not be 100% reliable.
// So to prevent infinite loop, we are checking number of auto replies sent to the customer recently.
$created_at = \Illuminate\Support\Carbon::now()->subMinutes(self::CHECK_PERIOD);
$auto_replies_sent = SendLog::where('customer_id', $conversation->customer_id)
->where('mail_type', SendLog::MAIL_TYPE_AUTO_REPLY)
->where('created_at', '>', $created_at)
->count();
if ($auto_replies_sent >= 10) {
return;
}
if ($auto_replies_sent >= 2) {
// Find conversations from this customer
$prev_conversations = Conversation::select('subject', 'id')
->where('customer_id', $conversation->customer_id)
->where('created_at', '>', $created_at)
->get();
foreach ($prev_conversations as $prev_conv) {
if ($prev_conv->subject == $conversation->subject && $prev_conv->id != $conversation->id) {
return;
}
}
}
// Do not send autoreplies to own mailboxes.
if ($conversation->customer_email) {
$is_internal_email = Mailbox::where('email', $conversation->customer_email)->exists();
if ($is_internal_email) {
return;
}
}
// 24h limit has been disabled: https://github.com/freescout-helpdesk/freescout/pull/95
// Send auto reply once in 24h
@@ -37,7 +101,7 @@ class SendAutoReply
return;
}*/
\App\Jobs\SendAutoReply::dispatch($conversation, $conversation->threads()->first(), $conversation->mailbox, $conversation->customer)
\App\Jobs\SendAutoReply::dispatch($conversation, $thread, $conversation->mailbox, $conversation->customer)
->onQueue('emails');
}
}

View File

@@ -1,7 +1,10 @@
<?php
/**
* Send notifications to users by email and in browser.
*/
namespace App\Listeners;
use App\Conversation;
use App\Subscription;
class SendNotificationToUsers
@@ -32,14 +35,21 @@ class SendNotificationToUsers
break;
case 'App\Events\UserAddedNote':
$caused_by_user_id = $event->thread->created_by_user_id;
$event_type = Subscription::EVENT_TYPE_USER_ADDED_NOTE;
// When conversation is forwarded only notification
// about child forward conversation is sent.
if (!$event->thread->isForward()) {
$event_type = Subscription::EVENT_TYPE_USER_ADDED_NOTE;
}
break;
case 'App\Events\UserCreatedConversation':
$caused_by_user_id = $event->conversation->created_by_user_id;
$event_type = Subscription::EVENT_TYPE_NEW;
break;
case 'App\Events\CustomerCreatedConversation':
$event_type = Subscription::EVENT_TYPE_NEW;
// Do not send notification if conversation is spam.
if ($event->conversation->status != Conversation::STATUS_SPAM) {
$event_type = Subscription::EVENT_TYPE_NEW;
}
break;
case 'App\Events\ConversationUserChanged':
$caused_by_user_id = $event->user->id;
@@ -52,12 +62,13 @@ class SendNotificationToUsers
if (empty($event->conversation) || !$event_type) {
return;
}
// Ignore imported threads.
if (!empty($event->thread) && $event->thread->imported) {
return;
}
$conversation = $event->conversation;
// We can not check imported here, as after conversation has been imported via API
// notifications has to be sent.
//if (!$conversation->imported) {
// Using the last argument you can make event to be processed immediately
Subscription::registerEvent($event_type, $conversation, $caused_by_user_id/*, true*/);
}

View File

@@ -23,11 +23,45 @@ class SendReplyToCustomer
{
$conversation = $event->conversation;
// Do not send email if this is a Phone conversation and customer has no email.
if ($conversation->isPhone()) {
if (!$conversation->customer->getMainEmail()) {
return;
}
}
$replies = $conversation->getReplies();
// Ignore imported messages.
if ($replies && $replies->first() && $replies->first()->imported) {
return;
}
// Remove threads added after this event had fired.
$thread = $event->last_thread ?? $event->thread ?? null;
if ($thread) {
foreach ($replies as $i => $reply) {
if ($reply->id == $thread->id) {
break;
} else {
$replies->forget($i);
}
}
}
// Chat conversation.
if ($conversation->isChat()) {
\Helper::backgroundAction('chat_conversation.send_reply', [$conversation, $replies, $conversation->customer], now()->addSeconds(Conversation::UNDO_TIMOUT));
return;
}
// We can not check imported here, as after conversation has been imported via API
// notifications has to be sent.
//if (!$conversation->imported) {
\App\Jobs\SendReplyToCustomer::dispatch($conversation, $conversation->getReplies(), $conversation->customer)
->delay(now()->addSeconds(Conversation::UNDO_TIMOUT))
$delay = \Eventy::filter('conversation.send_reply_to_customer_delay', now()->addSeconds(Conversation::UNDO_TIMOUT), $conversation, $replies);
\App\Jobs\SendReplyToCustomer::dispatch($conversation, $replies, $conversation->customer)
->delay($delay)
->onQueue('emails');
}
}

View File

@@ -2,8 +2,6 @@
namespace App\Mail;
use Illuminate\Container\Container;
use Illuminate\Contracts\Mail\Mailer as MailerContract;
use Illuminate\Mail\Mailable;
class Alert extends Mailable
@@ -20,7 +18,6 @@ class Alert extends Mailable
/**
* Create a new message instance.
*
*/
public function __construct($text, $title = '')
{
@@ -35,6 +32,8 @@ class Alert extends Mailable
*/
public function build()
{
\MailHelper::prepareMailable($this);
$subject = '['.\Config::get('app.name').'] ';
if (!empty($this->title)) {
$subject .= $this->title;

View File

@@ -2,41 +2,32 @@
namespace App\Mail;
use Illuminate\Bus\Queueable;
use Illuminate\Container\Container;
use Illuminate\Contracts\Mail\Mailer as MailerContract;
use Illuminate\Mail\Mailable;
use Illuminate\Queue\SerializesModels;
class AutoReply extends Mailable
{
/**
* Conversation created by customer.
*
*/
public $conversation;
/**
* Mailbox.
*
*/
public $mailbox;
/**
* Customer.
*
*/
public $customer;
/**
* Custom headers.
*
*/
public $headers = [];
/**
* Create a new message instance.
*
*/
public function __construct($conversation, $mailbox, $customer, $headers)
{
@@ -53,6 +44,8 @@ class AutoReply extends Mailable
*/
public function build()
{
\MailHelper::prepareMailable($this);
$view_params = [];
// Set headers
@@ -65,8 +58,10 @@ class AutoReply extends Mailable
];
// Set variables
$subject = \App\Misc\Mail::replaceMailVars($this->mailbox->auto_reply_subject, $data);
$view_params['auto_reply_message'] = \App\Misc\Mail::replaceMailVars($this->mailbox->auto_reply_message, $data);
$subject = \MailHelper::replaceMailVars($this->mailbox->auto_reply_subject, $data);
$view_params['auto_reply_message'] = \MailHelper::replaceMailVars($this->mailbox->auto_reply_message, $data);
$subject = \Eventy::filter('email.auto_reply.subject', $subject, $this->conversation);
$message = $this->subject($subject)
->view('emails/customer/auto_reply', $view_params)

View File

@@ -2,12 +2,7 @@
namespace App\Mail;
use App\Option;
use Illuminate\Bus\Queueable;
use Illuminate\Container\Container;
use Illuminate\Contracts\Mail\Mailer as MailerContract;
use Illuminate\Mail\Mailable;
use Illuminate\Queue\SerializesModels;
class PasswordChanged extends Mailable
{
@@ -18,7 +13,6 @@ class PasswordChanged extends Mailable
/**
* Create a new message instance.
*
*/
public function __construct($user)
{
@@ -32,6 +26,8 @@ class PasswordChanged extends Mailable
*/
public function build()
{
\MailHelper::prepareMailable($this);
$message = $this->subject(__('Password Changed'))
->view('emails/user/password_changed')
->text('emails/user/password_changed_text');

View File

@@ -2,11 +2,9 @@
namespace App\Mail;
use Illuminate\Bus\Queueable;
use Illuminate\Container\Container;
use Illuminate\Contracts\Mail\Mailer as MailerContract;
use Illuminate\Mail\Mailable;
use Illuminate\Queue\SerializesModels;
// https://medium.com/@guysmilez/queuing-mailables-with-custom-headers-in-laravel-5-4-ab615f022f17
//abstract class AbstractMessage extends Mailable
@@ -40,17 +38,29 @@ class ReplyToCustomer extends Mailable
*/
public $mailbox;
/**
* Subject.
*/
public $subject;
/**
* Number of threads.
*/
public $threads_count;
/**
* Create a new message instance.
*
* @return void
*/
public function __construct($conversation, $threads, $headers, $mailbox)
public function __construct($conversation, $threads, $headers, $mailbox, $subject, $threads_count = 1)
{
$this->conversation = $conversation;
$this->threads = $threads;
$this->headers = $headers;
$this->mailbox = $mailbox;
$this->subject = $subject;
$this->threads_count = $threads_count;
}
/**
@@ -60,18 +70,58 @@ class ReplyToCustomer extends Mailable
*/
public function build()
{
\MailHelper::prepareMailable($this);
$thread = $this->threads->first();
$from_alias = trim($thread->from ?? '');
// Set Message-ID
// Settings via $this->addCustomHeaders does not work
$new_headers = $this->headers;
if (!empty($new_headers)) {
$this->withSwiftMessage(function ($swiftmessage) use ($new_headers) {
if (!empty($new_headers['Message-ID'])) {
$swiftmessage->setId($new_headers['Message-ID']);
if (!empty($new_headers) || $from_alias) {
$mailbox = $this->mailbox;
$this->withSwiftMessage(function ($swiftmessage) use ($new_headers, $from_alias, $mailbox, $thread) {
if (!empty($new_headers)) {
if (!empty($new_headers['Message-ID'])) {
$swiftmessage->setId($new_headers['Message-ID']);
}
$headers = $swiftmessage->getHeaders();
foreach ($new_headers as $header => $value) {
if ($header != 'Message-ID') {
$headers->addTextHeader($header, $value);
}
}
}
$headers = $swiftmessage->getHeaders();
foreach ($new_headers as $header => $value) {
if ($header != 'Message-ID') {
$headers->addTextHeader($header, $value);
if (!empty($from_alias)) {
$aliases = $mailbox->getAliases();
// Make sure that the From contains a mailbox alias,
// as user thread may have From specified when a user
// replies to an email notification.
if (array_key_exists($from_alias, $aliases)) {
$from_alias_name = $aliases[$from_alias] ?? '';
// Take into account mailbox From Name setting.
$mailbox_mail_from = $mailbox->getMailFrom($thread->created_by_user, $thread->conversation);
if ($mailbox_mail_from['name'] == $mailbox->name && $from_alias_name) {
// Use name from alias.
} else {
// User name or custom.
$from_alias_name = $mailbox_mail_from['name'];
}
$swift_from = $headers->get('From');
if ($from_alias_name) {
$swift_from->setNameAddresses([
$from_alias => $from_alias_name
]);
} else {
$swift_from->setAddresses([
$from_alias
]);
}
}
}
@@ -79,20 +129,19 @@ class ReplyToCustomer extends Mailable
});
}
$subject = $this->conversation->subject;
if (count($this->threads) > 1) {
$subject = 'Re: '.$subject;
}
// from($this->from) Sets only email, name stays empty.
// So we set from in Mail::setMailDriver
$message = $this->subject($subject)
$message = $this->subject($this->subject)
->view('emails/customer/reply_fancy')
->text('emails/customer/reply_fancy_text');
if ($this->threads->first()->has_attachments) {
foreach ($this->threads->first()->attachments as $attachment) {
$message->attach($attachment->getLocalFilePath());
if ($thread->has_attachments) {
foreach ($thread->attachments as $attachment) {
if ($attachment->fileExists()) {
$message->attach($attachment->getLocalFilePath());
} else {
\Log::error('[ReplyToCustomer] Thread: '.$thread->id.'. Attachment file not find on disk: '.$attachment->getLocalFilePath());
}
}
}

View File

@@ -2,8 +2,6 @@
namespace App\Mail;
use Illuminate\Container\Container;
use Illuminate\Contracts\Mail\Mailer as MailerContract;
use Illuminate\Mail\Mailable;
class Test extends Mailable
@@ -12,7 +10,6 @@ class Test extends Mailable
/**
* Create a new message instance.
*
*/
public function __construct($mailbox = null)
{
@@ -26,6 +23,15 @@ class Test extends Mailable
*/
public function build()
{
\MailHelper::prepareMailable($this);
$this->withSwiftMessage(function ($swiftmessage) {
$headers = $swiftmessage->getHeaders();
$headers->addTextHeader('X-FreeScout-Mail-Type', 'test.mailbox');
return $swiftmessage;
});
$message = $this->subject(__(':app_name Test Email', ['app_name' => \Config::get('app.name')]));
if ($this->mailbox) {
$message->view('emails/user/test', ['mailbox' => $this->mailbox]);

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