This addresses issue 6817 where when using an OR operator in the Regular
Expression validation textbox for a Short Answer field it gets removed
without warning. This is due to a malformed Regex statement within the
`Format::strip_emoticons()` function. This simply removes the brackets
from the OR comparison as brackets are only used for range comparisons
(eg. `/[\x{2310}-\x{231F}]/u`). Additionally, this replaces the
duplicated Copyright symbol with the "masculine" version of degree to
cover both types of degree symbols. There are more but these are the
most common.
This ensures the actor's login name is of an acceptable format before
attempting authentication. This also updates `is_userid()` to accept a
new param of `$verify` that is passed through to `is_email()`.
This addresses an issue where when updating a Help Topic and having a
disabled Department set for example, the system will return a generic
error stating to address the errors below; but none are shown. This is
due to a missing error div that displays the Department errors. This
simply adds the div so Department errors are visible.
This addresses an issue where MS started adding UTF-8 BOM to beginning
of some content which causes parsing issues and errors. This removes the
UTF-8 BOM before using it in laminas to avoid parsing issues and errors.
This addresses an issue with PGP and S/MIME mail parsing where sometimes
the content is completely empty or malformed. This is due to an old PGP
block that was added back to the code after a Pear upgrade. This removes
the block to allow PGP and S/MIME mail to be parsed correctly.
This addresses an issue where having multiple Interval values for a
single Date column (like DueDate) throws a fatal error. This is due to
the system expecting the interval to be a string not an array. This adds
a cast to each place we use the interval to ensure it's a string to
avoid fatal errors.
This addresses an issue with POP OAuth2 error parsing where errors are
blank on screen. This is due to using `$matches[2]` (which doesn't
exist) vs `$matches[1]`. This updates the code to use the correct match
so that errors are correctly shown on screen.
This addresses 6873 where SVG Image uploads are failing even with strict
MIME checking disabled. This is due to the `exif_imagetype()` call that
checks an image MIME type. This method does not work well with SVGs as
it only checks the first few bytes. This adds a specific SVG check using
`mime_content_type()` that can handle SVG MIME type checks.
This adds backwards compatibility support for legacy mail servers that
don’t support SMTPUTF8 or ones that simply refuse to support it (get
with the times old man!). When the system adds an attachment or adds an
inline image to outbound mail we add the raw UTF-8 filename to the
`filename=` parameter contained within the `Content-Disposition` header.
This can be problematic with legacy mail servers or servers that refuse
to support SMTPUTF8 as non-ASCII characters contained within the
`filename=` parameter of the `Content-Disposition` header triggers
SMTPUTF8 requirement. If the server doesn’t support it but it’s required
then it bounces the mail, typically with an error message stating such.
This updates the `Message::addInlineImage()` and
`Message::addAttachment()` methods to not only provide an ASCII-safe
filename but to also utilize a new MIME Part `Rfc2231Part` (discussed
momentarily). To generate said ASCII-safe filenames for both inline
images and any attached files this adds a new method called
`Message::asciiFallback()` that converts raw UTF-8 filenames to ASCII as
well as removes any non-header safe characters. In addition, this adds a
new MIME utility namespace `osTicket\Mime` that houses a new MIME
utility called `Rfc2231Part`. This class extends `Laminas\Mime\Part` to
essentially modify the `Content-Disposition` header and tack on the
original UTF-8 filename using the `filename*=UTF-8''` parameter but
encoded with `rawurlencode()` to make it ASCII-safe.
In summary, this adds an ASCII-safe `filename=` parameter to the
`Content-Disposition` header to prevent legacy servers from triggering
SMTPUTF8 requirement whilst utilizing `Rfc2231Part` to additionally
provide an (ASCII-safe) UTF-8 `filename*=UTF-8''` parameter for modern
mail servers (preserving the original filename).
This addresses an issue where if you update the User Account
Confirmation Email template for example and it has validation errors the
system will throw a fatal error. This is due to a missing `$langs`
variable and a missing `$cfg` global. This adds the missing variable and
global back to avoid fatal errors.
This addresses an issue where Guest User sessions would quickly timeout
even though the User session was configured for say 24 hours. This was
due to a chuck of code that used `min()` to get the minimum value from
the various TTL. This removes the `min()` part so it uses the `$ttl` if
available else defaults to `$maxlife`/`SESSION_TTL`.
This addresses a vulnerability reported by Muhammad Umer Adeem
(@UmerAdeemCheema) where normal Agents can potentially view system logs.
This also addresses additional access vulns with AJAX Content.
The previous implementation used the regex `/:(\d+)/i` to remove a
single colon preceding digits. However, this approach did not handle
cases with multiple colons (e.g., "::1"), which could potentially allow
for injection attempts.
This commit updates the regex to `/:+(\d+)/` to match one or more colons
before the digits and replaces them with just the captured number. This
change ensures that all leading colons are removed, effectively
neutralizing any parameter marker injection while preserving the
intended numeric value.
This addresses an issue with iFrame logins where the site simply would
refuse to honor cross site cookies. This adds a new check to see if the
system allows iFrames. If so, it will set the `samesite` for the cookie
to `None` which allows the cookie to be sent in all contexts. If the
site does not allow iFrames it will default to `Strict` for security
reasons.
This makes the changes needed to fully support Crowdin's latest API v2.
The main changes are the endpoints and the response types. Previously
the base URL was structured like `/api/project/{project}/{command}`
however now it is structured like
`/api/v2/projects/{project_id}/{command}`. Also previously the response
types were XML whereas now they are all JSON. There are other small
changes however their is a new function added called `getBranchId()`
that retrieves the given Branch's ID (to be used in URLs and the build
stage).
This addresses an issue where Base64 encoding plain-text content leads
to raw encoded data being displayed in the mail client. This removes the
Base64 encoding from plain-text emails so the content displays properly.
To note, when you look at providers like Gmail, etc. they do not Base64
encode Plain-text nor HTML content.
This addresses issue 6647 where in certain scenarios/setups the system
throws the infamous `Excessive errors processing emails for` error. As
per the information from the referenced issue the main cause is a fatal
error where `json_decode()` is receiving an array instead of the
expected string. This adds a check on `$fieldClean[0]` to see if it's a
string and if so uses the `json_decode()` otherwise it uses itself.
This addresses issue 6772 where you can access a Canned Response with a
Department set even if you don’t have the Premade Role Permission for
the Canned Response's Department. This is due to not checking access
before displaying the Canned Response. This adds a new function called
`staffCanAccess()` to class Canned that checks to see if the Canned
Response has a Department and if so ensures the Agent has a Role in that
Department and that the Role contains the Premade Permission. This adds
a new `if()` statement that calls `staffCanAccess()` if a Canned
Response is found.
This addresses the deprecation of the `E_STRICT` constant. The upstream
error level has been removed and now the constant is being deprecated.
Since we don't support PHP 5.x any longer and this is now
deprecated/removed this fully removes the last mention of the `E_STRICT`
constant. So long and farewell my friend.
Reference:
https://www.php.net/manual/en/errorfunc.constants.php#constant.e-strict
This addresses the deprecation of an implicitly nullable parameter
followed by a mandatory parameter in the old suggested format. This
updates the old suggested format of `function name(?string $var=null,
$var2)` to the newly suggested format of `function name(?string $var,
$var2)`. This is to avoid warnings but to also avoid errors in the
future.
Reference:
https://www.php.net/manual/en/migration84.deprecated.php#migration84.deprecated.core.implicitly-nullable-parameter
This addresses an issue where having a Ticket Referred to you and one of
your Departments increases the Queue count erroneously. In the
`getTicketsVisibility()` function the system adds criteria to find
Tickets referred to the Agent and then later adds separate criteria to
find Tickets referred to the Agent’s Department(s). The problem is the
two separate criteria will make the same Ticket appear twice in the
results. To fix the issue we simply need to make the results distinct
via `ticket_id`. Since `getTicketsVisibility()` is essentially
generating an array of criteria we can’t add the distinction there.
Plus, it could be used for things other than counts. So we move on to
`applyVisibility()` where we use the criteria and add the distinction
there. To note, this function is only used in `SavedQueue::counts()` and
`SavedQueue::getTotal()` which would only affect counts; just what we
want.
This addresses an issue where when using `getTotal()` to get the total
counts for a Queue it mistakenly includes Children Tickets. This causes
a discrepancy between the number of Tickets shown within the Queue vs
the total shown for the count. Since we ignore Children Tickets within
the Queues themselves (due to them being merged into a Parent) we should
also ignore Children within the Queue Counts. This adds a new filter to
the `$query` in `getTotal()` that filters Tickets with `ticket_pid`
equal to `NULL` or Tickets with `flags` containing `Ticket::FLAG_LINKED`
(ie. it is a Link not Merge).
This addresses an issue where if you are importing Users via CSV,
one of the Users already exists in the system, their profile has a
Department Field with a current value set, and the CSV row for their
account has a Department Field value the system will fail with an error
of `Cannot access offset of type string on string`. This is due to
blindly assuming the `$value` is an array. This adds a check to see if
the value is an array, if so it will use the `$id` otherwise it defaults
to the `$value`.
This addresses osTicket/osTicket-plugins#293 where attempting to lookup
and select a User from an external source like LDAP with an umlaut in
their name causes an error of "User not found". This is because the URL
is encoded with `htmlentities()` which makes the umlaut character
unrecognizable. This wraps the lookup string with `html_entity_decode()`
so that the umlaut is preserved and lookup succeeds.
This addresses 6574 and other deprecations and warnings encountered
during testing with `error_reporting` set to `E_ALL` and both
`display_errors` and `display_startup_errors` enabled. This includes
defining optional parameters before required parameters and function
return types not matching their parent.
This addresses 6758 where enabling the ACL for Clients and attempting to
download a file as an Agent throws an Access Denied error. This adds a
check in the `check_acl` function to see if the backend is set to Client
Portal and if the current authenticated person is an Agent. If so, it
will skip the ACL check; otherwise it will enforce the check.
This is a rewrite of 6757 that updates the `symfony/process` package to
address a recent security advisory (11/2024). Both osTicket and
laminas-mail does not use this package in production (only in dev mode)
so this only updates the `require-dev` section of the main
`composer.json` file as well as the `composer.lock` file. This is so
that if anyone uses it in dev mode they will be using the latest patched
version of `symfony/process`.
Since this package is not in-use below are the specific instructions used to
update it without installing it:
```
cd include/laminas-mail/
composer require --dev --no-update symfony/process
vim composer.lock
-- Update symfony/process version to latest (v6.4.14)
-- Update the `reference` for the source and distribution to commit hash
-- Update the `time`
composer update --no-install --lock
```
This addresses an issue where the `comments` variable is not replaced in
the Ticket Transfer Alert if there is no comment provided. This adds a
ternary operator to the `comments` variable assignment to see if there
is a value. If so it will use the value if not it will default to an
empty string. This is so the variable can be replaced with nothing which
is the intended end result.
This addresses an issue where `-` characters are allowed in Field
Variable Names when they shouldn't be. Reason being is dashes are not
allowed in MySQL Column names. Since we use the Field Variable Name as
the Column name in the respective CDATA table we cannot allow the dashes
in the Variable Names.
This temporarily addresses 6661 where there are a few MariaDB warnings
after `sql_mode` changes. This only includes temporary changes via code
until we enforce defaults via SQL in the next major release. This
accomplishes the following:
- Ensures a `body` is set when creating Drafts
- Ensures a `logger` is set when adding system logs
- Ensures `updated` has a date-time set when creating a new ThreadEntry
- Ensures `staff_id`|`team_id` defaults to `0` if no object ID available
- Ensures the `lock_id` is set to `0` instead of `NULL`
Enforce Strict Mode when updating / saving OAuth2 credentials. At the
moment we force the check at the plugin level which is not ideal and
will be removed in the near future.
In addition the change include setting the correct error tag so we can
show the error message in context.
This addresses an issue where attempting to import a User with a value
for a Custom List fails to import the list item. This is due to the
parsed (JSON) value being passed to `SelectionField::parse()` which
doesn't know how to parse it. This pull updates the `if()` statement
that checks if the given value is not an array and adds
`JsonDataParser::parse($value) ?:` before the `array($value)` to see if
we can successfully parse the string. If so, it will use the parsed
array. If not, it falls back to manually converting the value into an
array.
This addresses an issue where when annotating an image and sending it,
it disappears from the final reply. This is due to REGEX that attempts
to detect inline images and determines if it should strip them or not.
This REGEX statement is greedy which means it will find as many matches
as possible. This is a problem for image annotation as one of the
classes that gets added to the image is `data-orig-annotated-image-src`.
This gets picked up by the REGEX and as a result causes the image to be
rejected since it contains a file URL instead of the expected `cid`.
This pull simply changes the first matching group to "lazy" so that it
stops on the first match. This causes the real `src` value to be picked
up and parsed which contains the expected `cid`.
This addresses an issue where attempting to export a multiselection List
Field with multiple selected items only shows the first selected item.
This is due to the Item IDs containing spaces (due to the earlier
`explode()` call) so the IDs do not match the available IDs. This adds a
`trim()` around the Item IDs so that they match appropriately.
This addresses an issue where adding a `duedate` to API request payloads
the system simply ignores it. This is due to an _old_ bit of code (1.7 -
circa 2013) that refuses the `duedate` from any source other than
`staff`. This updates the check from `strcasecmp()` to `in_array()` so
it can check for both `staff` and `api`. This will allow a `duedate` to
manually be set from Staff created Tickets as well as API created
Tickets.
In addition, this updates the `getRequestStructure()` function to change
the single `strcasecmp()` for `email` to a `switch {}`. This is so we
can check multiple types other than `email`. This adds the previous
`email` format as a case and adds two new cases for `json` and `xml`
formats. Within these two new cases `duedate`, `slaId`, and `staffId`
are added as available fields. This is so the system doesn’t throw an
`Unexpected data received in API request` error even though these fields
are valid and accepted with JSON and XML payloads.
This addresses an issue where Safari is now refusing to load inline
images stored in S3. Upon investigation it was found the code had an old
check for Safari browser when generating the content disposition
filename string. If Safari was being used it left the filename alone as
"Safari and only Safari can handle the filename as is". Well this may be
true for Safari however S3 cannot handle this. This removes the Safari
specific check and forces even Safari to UTF8 encode the filename for
the content disposition string. This allows Safari to load inline
images from S3 again. Safari still loads other images, etc. just fine as
well.
This addresses an issue reported by JensEB where the wrong remote
backend name was used in a strpos check. This updates the name from
`auth_bk` to the correct `mailbox_auth_bk`.
This updates the PHP Prerequisites to include the `iconv` extension.
Iconv methods are used for email parsing (in the pear/Mail_mimeDecode
package) as well as other places internally. This adds the extension to
the installer prerequisites as well as the system information page and
the `README.md`.
This removes a function called `Mail_mimeDecode` that was added in
`cbd78ac` (originally from pull #6681) for "backwards compatibility".
Upon investigation this is not needed; so it will be removed.
This reapplies the Memory Optimizations added with `5ae4fe6`, `c1d0b05`,
`2c00654`, `87277dd`, and `c57c22a`. This ensures larger emails are
parsed correctly and as optimal as possible. Without optimizations, the
system typically fails at parsing such large emails.
This addresses an issue where if you load the User Directory, click the
Organization tab, go back to the User Directory tab, and attempt a user
lookup via basic-search it attempts to hit the url `undefined?q=xxx`
which is obviously not valid and fails to return results. After
investigation it was found that when clicking through the tabs vs
directly loading them causes the Javascript/jQuery to load in reverse
sequence. This means core `scp/js/scp.js` code was taking precedence
over the inline-jQuery within the Users Staff Template. In most cases
this shouldn't matter however in this particular case the input selector
in the core `scp/js/scp.js` was looking for a generic
`input.basic-search` class. We use this class for all basic searches
however the ones for user lookup and organization lookpup respectively
have their own unique ID in addition that the inline-jQuery is supposed
to select. Since the core is loading after the inline in this case that
means the core takes precedence over the inline code causing wrong URL,
etc. This simply updates the core selector to have `:not([id])` so that
it doesn't try to match an iput with class of `input.basic-search` with
an ID. Tested and working with User/Org lookups and all other
basic-searches.
This addresses an issue where when viewing a Parent/Child Ticket that
also has Tasks and you first click the Tasks tab, then the Related
Tickets tab, then finally click a Related Ticket the browser redirects
to `/scp/ickets.php?=xxx` with URL Not Supported error. This is due to
reusing the class name `tasks` for the related Tickets table. This
changes the `tasks` class to `relations` so that it's unique.
This addresses an issue where sometimes mail does not have a From Address
which causes issues in `Mail_Parse::parseAddressList()`. First, this adds a
check to see if the from is set in the headers, if not we return. Next, this
adds a check to see if the From header is malformed (ie. missing a bracket),
if so it adds one. Lastly, this continues to call `parseAddressList()` as
before however this time the From should always be set.
This addresses an issue where when exporting Agents and an Agent doesn't
have a Permission or Permission lookp fails the system throws a fatal error.
This is because we try to use `array_keys()` on `null`/`false`. This
updates class Role's `getInfo()` function to return an empty array if
the `perms` are not set/null/etc.
This updates the PHP version in the System Prerequisites (used in the
installer and upgrader) from 8.0 to 8.1. Since upstream PHP dropped support
for it we will too. RIP
This addresses an issue where in PHP 8.3 our declaration of `mb_str_pad()`
conflicts with the native `mb_str_pad()`. This adds a check to see if the
function already exists or not before declaring it.
In PHP 8.3 they have deprecated the use of `get_class()` with no parameters.
Instead you should use `get_class($this)`, `self::class`, or `__CLASS__`.
This updates all calls in the code to make it 8.3 compliant. These changes
are backwards compatible with PHP 8.1-8.2.
This addresses an issue where passing a full From string (eg. `"osTicket
Alerts" <user@noemail.com>`) as the `$from` parameter for
`Mailer::sendmail()` causes a fatal laminas-mail error. This is due to the
full string being reformatted after it's already been formatted. This
adds a check for `<` and if present we will not reformat; we will
instead use the full string as-is. This also updates one of the calls
and adds a space between the display name and the actual address.
Update the mimeDecode.php file, which was originally version 1.48 from 2006/12/03 and has been maintained up to now. Currently, we are directly using version 1.5.6. Adjustments were made to the syntax while retaining the original getHeader() function.
This is to fix#6680 issue.
This fixes a casing issue in the handling of the Action header while
handling bounce notices from mail servers.
Prior to this change, no emails could be flagged as a bounce email
because the Upper-Case version of Action was used. This has been
lowercases to "action".
An accompanying unit test, tests that a bounce email is properly passed
and it's attributes are setup. I have redacted a sample DSN email as
much as I thought was necessary but am happy to re-review this fixture.
As all other header access appears to be lowercase, this just appears to
be a simple typo.
This fixes:
https://forum.osticket.com/d/104433-undelivered-mail-returned-to-sender-processing
too
A huge thank you to: Hikari Akimori from the Resonite community for
their sanity checks.
This removes the custom `prepareHeaders()` method from class Sendmail as
this functionality was added upstream which is now available with the
latest update.
This addresses an issue where if the `ticket` array key is missing in the
`$current` array it will throw a fatal error. This adds an `isset()` check
to ensure the array key exists and is set before using it.
This updates the minimum required MySQL Version from 5.0 to 5.5. We've
stated "5.5 or better" for a while but never actually enforced it in our
installer/upgrader.
This addresses issue 6573 where the `lang` URL param is not sanity checked
and throws a fatal error if it contains anything but a string. This forces
the `lang` param to a string when passing to `strtolower()` to avoid fatal
errors. The `isLanguageInstalled()` function will still behave the same way
as before by returning `false` if passed an invalid `lang` code -or- if the
`lang` code is valid just doesn't exist in the available languages.
This updates the PHP Prerequisites to include the `ctype` extension needed
for email fetching as part of the `laminas-mail` package. This adds the
extension to the installer prerequisites as well as the system information
page and the `README.md`. Lastly, this updates the installer prerequisites
wording and structure so they all match and look streamlined.
This addresses an issue where Agents cannot see Referred Tickets in their
Closed Queues. This is due to the `Staff::getTicketsVisibility()` function
blindly using the `open` state instead of looking for `closed` as well. This
updates the function to include the `closed` state in the status condition.
This ensures the referred Tickets are shown in every Queue.
This addresses an issue where using a non-english language breaks the Ticket
view page for Tickets with no Due Date, SLA with grace period longer than 41
hours, and the SLA is attached to a Schedule with working days. This is due
to mistakenly translating the day names in `getDays()` function at times we
shouldn't be. PHP only likes English day names during actual date
calculations. This adds a new method called `getTranslatedDays()` that will
return the translated day names when needed (it also caches the
translations). In addition this updates the existing `getDays()` to strictly
return the native, untranslated day names. Lastly, this updates the calls to
`getDays()` that need to be translated to `getTranslatedDays()`.
This addresses an issue where `Task::getLastRespondent()` returns the wrong
Agent leading to the wrong people receiving alerts, etc. This updates the
`Task::getLastRespondent()` function to make it limit the last respondent
search to the Task's own Thread Entries rather than searching through all
entries.
This is a rewrite of #6641. This addresses an issue where if PHP has MySQLi
Error Reporting enabled (enabled by default starting with PHP 8.1), there
are multiple configured database hosts, and one host fails to connect the
system throws a fatal error. We previously attempted to silence fatal errors
with `@` suppression however STRICT MySQLi Error Reporting bypasses this and
still throws an error. This updates the `db_connect()` and
`db_select_database()` calls in `bootstrap.php` and wraps them with a
try/catch. If either `db_connect()` or `db_select_database()` throws a fatal
exception we will catch it and set `$ferror` to the exception message. Doing
so ensures the system attempts to connect to all configured hosts without
exiting and only croaks when no hosts are reachable or the database cannot
be selected.
This addresses an issue where the current REGEX for the "position" styling
attribute is causing issues when emails contain legit text like "position:
100 degrees". This updates the REGEX to only look for one of the possible
values instead of looking for seemingly anything.
This addresses an issue where when using a Checkbox on an Email Template the
variable is replaced with `1` if checked and doesn't get replaced at all if
unchecked. This is due to the `BooleanField` class not having an `asVar()`
method so it uses the `FormField::asVar()` method which calls `to_php()`.
This method returns an integer for BooleanField which is not what we want.
This adds a new method called `asVar()` to the `BooleanField` class that
calls `toString()` which will return `Yes` if checked and `No` if unchecked.
This addresses a small issue where the Department Name is not translated
on the Task Queues. This is due to the Task values missing the
Department ID used to generate the object_hash for the translation
table. This adds the `dept_id` to the Task Values so the translations
are properly found.
This addresses a small issue where the osTicket class could not be found in
manage.php. This moves the boostrap.php include above the osTicket call to
ensure the class is loaded before use.
This addresses a small bug where `Format::viewableImages()` was using
unencoded quotes instead of encoded quotes to replace the `<img src=`
matches. This means when the content is added to a textarea’s
`draft-data-original` attribute the unencoded quotes break the attribute
and displays raw HTML content. This moves the `Format::htmlchars()` call
after the `preg_replace_callback()` so the quotes can be properly
encoded (if needed).
This addresses an issue where saving edits made to a canned response with two
or more inline images either breaks the page or causes 500 error. This is due
to incorrectly formatted array of IDs for the inline images causing further
issues with `$att->file->getId()` on render.
This adds a check in `keepOnlyFileIds()` to see if the `$value` from the array
of IDs is an array itself. If so, we will break apart the `$value` array into
`$id` (File ID) => `$value` (File Name) to match the expected format. If the
`$value` is not an array, it will use the existing format (as before). This is
important as we have two different array formats for the File IDs depending on
what method is called to generate them. We need to be able to account for both
formats. In addition, this adds the file name to the `$attachment` array in
`getAttachmentIds()` so we can save the new attachment name (if different).
Lastly, this fixes an issue where the Canned Response attachment upload field
was blindly including all attachments rather than excluding the inline images.
This addresses a small issue where when searching for a Choice/Selection
Field value using `includes` criteria it sometimes shows records it's
not supposed to. This is due to the REGEX used to find the value. Let's
say you have two different List Options:
1. ID = 2 | Value = List Item 2
2. ID = 22 | Value = List Item 22
Now, let’s say you make a search criteria of `List => Includes => List
Item 2`. The REGEX we use is `\"?2(\"|,|$)` which will essentially match
`*2` instead of just `2`. This means it will include Tickets with with
values of `List Item 22` as it contains a `2` as well.
This updates the REGEX to add `(?<![0-9])` before the ID/Key to ensure
it does not match numbers that contain this ID/Key. Instead it will have
to be an exact match of the ID/Key.
This fixes an issue where sometimes the holidays for schedules can be
empty. This adds checks to see if holidays is empty/not set in the POST
and if so we try to get the Schedule's existing Holidays and if they
don't exist we default to an empty array. This also adds a further check
to see if `$holidays` is set if not then we default to an empty array.
This adds the concept of Retry Codes so we can attempt to reconnect to
MySQL in the event of certain error codes (2006 and 1213).
2006 - MySQL server has gone away
1213 - Deadlock found when trying to get lock; try restarting
transaction
This adds code to append the offending mail headers when an Email Loop
is detected. This will provide more information on what email exactly is
causing the loop.
This addresses an issue where sometimes an Agent will add Search
criteria with `!includes` but don't add a value. This adds a check to
make sure there is a value before attempting the search. If there is no
value we simply return without executing the search to avoid errors.
This addresses an issue where sometimes the returned `$data` from the
parser can be a type other than an array. We expect the data to be an
array so to avoid issues/errors this adds a check to ensure `$data` is
an array before we use it.
This addresses an issue where sometimes attachments can sometimes not be
set in the `$data` array. This adds a check to ensure attachments key
isset in the `$data` array before attempting to use it.
This addresses an issue where inline images were being broken in FAQ
Category Notes. This ensures we call `Format::viewableImages()` on both
the Category Description and Notes to ensure they are sanitized and
properly formatted.
This addresses an issue where having more than 20 ticket statuses run
off the page when selecting ticket statuses from Changes Status action
button. This adds a check for how many status you have an if more than
20 we add styling so the list is scrollable.
This addresses an issue where if using an old database such as v1.6 ST
and attempting to upgrade you get a fatal error of
`osTicket\Session\SystemSessionHandler: must implement
osTicket\Session\AbstractSessionhandler`. This is because the
`SystemSessionHandler` class does not extend `AbstractSessionHandler`
(rightfully so). We seemingly force `AbstractSessionHandler` without
taking the `SystemSessionHandler` into account. This adds a check to see
if using `SystemSessionHandler` and if so sets `$impl` as such; allowing
the check to pass and the session to be initiated. This also updates the
capitalization of the `AbstractSessionhandler` class in two places.
This addresses an issue where when attempting to send mail from an
SmtpAccount we attempt to get the From name with `getName()` which
throws a fatal error. This updates class EmailAccount and adds a new
`getName()` method that gets the From name from the associated email
relation. This provides the needed name and prevents fatal error from
being thrown. In addition, this adds a further fail-safe where if no
name is returned we will use the email address as the name.
This updates the `include/class.i18n.php` file to fix issues with lang
codes. When building packs for languages with codes that have locales
(eg. `sv-SE`) the pack name use underscores, not dashes. This updates
the places we lookup by lang code and replaces `-` with `_` so they are
found correctly.
This updates the `css/flags.css` to correct the positioning of some
flags. This also adds `fil` code to the `include/i18n/langs.php` file to
account for Filipino language.
This updates the code to fix issues with the `Phrases-Version`,
`Language`, `Last-Revision`, and `Version` not being added properly in
the `MANIFEST.php` file on build. This is due to importing the wrong
class as well as incorrect key names. This updates the include_once
statement as well as the key names.
This is a partial rewrite of 6365. This moves the Upgrade section to the
`UPGRADING.txt` file and updates the verbiage to link to the Upgrade
Guide in the docs as well as the `UPGRADING.txt` file. In addition this
updates the recommended extensions for PHP to reflect what's shown in
Admin Panel > Dashboard > Information. Lastly, this updates various
links in the `README.md` and `UPGRADING.txt` files.
This addresses issue 6564 where `putenv()` may be disabled on some
hosts. This adds a check to make sure the function exists before calling
it to avoid fatal errors.
This updates the `README.md` file to include the newly supported PHP 8.2
as well as an update to add more verbiage to supported MySQL versions.
This also adds credit to `laminas-mail` in the OS projects listings.
This mitigates a vulnerability repoted by @endansdto where iFrame domain
can be bypassed due to bad regex. This updates the regex to ensure
proper filtering and checks.
This mitigates a vulnerability reported by @ManuelHu where files can
bypass checks if sent in the same request behind a valid file. This also
adds a space to fix an annoyance in the JS errors.
This is a two-part commit that includes a fix for inline images on
display and a patch for a possible vulnerability for Drafts. This
restructures the way we call Format::viewableImages() so that we call it
when displaying after we sanitize the data to ensure the images are not
broken. Secondly, this ensures Drafts do not skip the
`Format::htmlchars()` sanitization at all. This is a rewrite of #6511.
This updates the email included in the intial installation Ticket to
`feedback@osticket.com`. This also updates the Ticket information to
include details about the documentation site.
This addresses an issue where emails that contain only attachment(s)
fail to process correctly. This is due to there being no `parts` for
`$part`. This adds a check for `!$part->parts` and if true (no parts) we
call `getAttachments()` on just the `$part` itself.
With PHP 8.2 `glob()` now returns an empty array if all paths are
restricted instead of `false`. This updates the only check we have on
this to check for empty array instead.
This replaces the now deprecated `strftime()` with `date()`. This also
adds a TODO to class Format to replace an instance there. It will need
some refactoring though so we are leaving it out of this commit.
This addresses an issue where the Copy/Paste Import feature for Users
sometimes creates a duplicate account for an existing User. This occurs
when using a string like `User Name, email@domain.tld`, however, does
not occur when using a string like `User Name,email@domain.tld`. This is
due to the extra space after the comma as we are not trimming extra
spaces correctly. This adds `trim()` to the values before they are used
so that they correctly match existing values and avoids duplicates.
This addresses an issue where uploading a file throws an Invalid File
error even though the file is valid and there are no file restrictions.
This is due to doing `strcasecmp()` on a variable that is some times
empty. This adds a check to see if that variable has a value before
doing the comparison to avoid false positives. In addition, this adds a
new paramter called `$strict` that if true we run the mime type check.
By default `$strict` is false which skips the check. We will eventually
add a configurable setting to enable strict mime type check if preferred.
This addresses an issue where attempting to use `All` Event type in any
other language than English the export will fail. This removes the
translation method from `All` so that the English version is used for
the option's `key`. This doesn't affect the visible word as it gets
translated downstream.
This updates the email included in the intial installation Ticket to
`feedback@osticket.com`. This also updates the Ticket information to
include details about the documentation site.
This addresses an issue where emails that contain only attachment(s)
fail to process correctly. This is due to there being no `parts` for
`$part`. This adds a check for `!$part->parts` and if true (no parts) we
call `getAttachments()` on just the `$part` itself.
This mitigates a vulnerability repoted by @endansdto where iFrame domain
can be bypassed due to bad regex. This updates the regex to ensure
proper filtering and checks.
This mitigates a vulnerability reported by @ManuelHu where files can
bypass checks if sent in the same request behind a valid file. This also
adds a space to fix an annoyance in the JS errors.
This is a two-part commit that includes a fix for inline images on
display and a patch for a possible vulnerability for Drafts. This
restructures the way we call Format::viewableImages() so that we call it
when displaying after we sanitize the data to ensure the images are not
broken. Secondly, this ensures Drafts do not skip the
`Format::htmlchars()` sanitization at all. This is a rewrite of #6511.
With PHP 8.2 `glob()` now returns an empty array if all paths are
restricted instead of `false`. This updates the only check we have on
this to check for empty array instead.
This replaces the now deprecated `strftime()` with `date()`. This also
adds a TODO to class Format to replace an instance there. It will need
some refactoring though so we are leaving it out of this commit.
This removes the custom `prepareHeaders()` method from class Sendmail as
this functionality was added upstream which is now available with the
latest update.
This removes old and tired code from the login pages where we throw
`Http::response(422);` to "prevent browsers from suggesting saving the
username and password". This is no longer the case as browsers no longer
play by these rules. The only way to properly do this nowadays is to set
an attribute on the form tag to disable autocomplete. We don't want to
do this either as that would prevent password managers from autofilling
the auth info.
Throwing a 422 code prevents some setups from accepting logins due to
4XX codes being error codes in nature. Removing this code seemingly has
no negative impact whatsoever.
A short backstory, this was [originally a 401
code](a99b9ce81e)
to prevent browsers from suggesting saving the auth info. Later it was
[changed to a 422
code](772d5c59a9)
to make IE play nice.
This addresses an issue where the Copy/Paste Import feature for Users
sometimes creates a duplicate account for an existing User. This occurs
when using a string like `User Name, email@domain.tld`, however, does
not occur when using a string like `User Name,email@domain.tld`. This is
due to the extra space after the comma as we are not trimming extra
spaces correctly. This adds `trim()` to the values before they are used
so that they correctly match existing values and avoids duplicates.
This addresses an issue where inline images only used in canned
responses and saved before a draft could be generated would erroneously
be deleted by the orphan file cleanup routine. This caused the inline
images to appear broken on use as they no longer exist. This is due to a
check for a `draft_id` before creating an attachment record for each
inline file. We do not need to check for a `draft_id` as we always have
a `response` in the POST with the most current data (eg. there might be
content added before a new draft can be saved). This removes the checks
in both `create` and `update` cases so that attachment records can be
created (with `inline = 1`) to avoid being deleted by file cleanup.
This addresses an issue where we were checking strict matching when
using basic authentication. This is due to a small oversight in the smtp
save checks. This adds a line to check if auth_bk is set to oauth2
before checking strict matching.
This addresses a small annoyance where the thread entry actions dropdown
always appears below the subsequent thread entry. This can be very
annoying and even hide some of the options. This adds `z-index` of
`auto` to the `thread-entry` div so that the dropdown always appears on
top.
This addresses an issue where lint tests fails due to `getRealPath()`
not being defined. This is from SplFileObject so we just need to add a
stub to ignore it in the tests.
This mitigates a vulnerability reported by @indevi0us where XSS is
possible via the `period` parameter. This sanitizes the parameter values
before using them anywhere.
This mitigates a vulnerability reported by @indevi0us where XSS is
possible via the `q` parameter in organization lookups. This sanitizes
the parameter value before use as well as htmlchars it before adding to
JSON output.
This mitigates a vulnerability reported by @indevi0us where XSS is
possible via the parent_id parameter. This forces the parameter to an
INT so that there is no chance of XSS.
This mitigates a vulnerability reported by @edr4 where XSS is possible
via System Email. This adds sanitization to the email before
saving/displaying. This also forces the other options (topic,
department, etc.) to int so there is no chance of XSS.
This addresses an issue where when doing full Ticket edit with a
FileUpload field and you don't supply a file the form_entry_value for
the corresponding field updates to `false`. This causes an issue with IS
NULL criteria so this adds a check to see if a value is present, if not,
then we return `NULL` instead of JSON encoding a `false` string value.
This addresses an issue where some of the mPDF font files don't get
included due to the way we use the `preg_split()`. This adds the
remaining path parts to the `list()` and adds statements to update the
`$path` if such parts exist.
This addresses a small issue where when attempting to export Agents in
any Department you get a fatal error of calling non-static method
statically. This updates the export method for the Department class to
static so that exports will function and no errors are thrown.
This addresses an issue where `make-pot` command is not working
properly. This is due to PHP 8 changes that were never fully resolved.
We had to move away from the now deprecated `each()` so we switched to
`foreach()`. However, `foreach()` does not keep current position in the
iteration which we rely on for the `make-pot` command. However, you can
get around this by using `while($var = current())` and passing by
reference which keeps the current position.
This updates the Delete Token functionality to show a success/error
banner when deleting the token. If successful it will delete the Token
tab and content, load the IdP tab, and show a success banner with the
JSON content. On error it will simply show an error banner with the JSON
content.
This changes the default for Strict Matching from `false` to `true` so
that new emails are strict unless explicitly set otherwise. This also
adds some descriptive comments to the getter and setter.
This addresses some bugs found during testing. This adds a check to
`SmtpAccount::getConfig()` that ensures we have an email and
MailboxAccount before attempting to call `getConfig()` and adds
descriptive comments. This also removes the `isActive()` check from the
SmtpAccount `save()` method as we only care about if it's currently set to
active. Lastly, this changes the variable name for the email address
from `$email` to `$addr` so it doesn't conflict with the original
`$email` variable.
It's about damn time.. that we add ability to delete the OAuth2 Token.
This adds a new button to the Token tab that will allow you to delete
the current Token.
This is a rewrite of osTicket/osTicket-plugins#263 where it was
attempting to implement Strict Matching. This fully implements Strict
Matching and adds functionality to check for this when retrieving a
token and when saving SMTP with Same As Remote Mailbox. This also adds a
new disabled field to the General Settings to show what email will be
used as well as a help tip that further explains Strict Matching.
To prevent following error:
PHP Fatal error: Uncaught Error: Call to a member function getId() on bool in /.../include/class.session.php:314
Logged back trace:
PHP Fatal error: Uncaught Error: Call to a member function getId() on bool in /.../include/class.session.php:314
Stack trace:
#0 /.../include/class.session.php(336): osTicket\\Session\\AbstractSessionStorageBackend->getRecord()
#1 /.../include/class.session.php(281): osTicket\\Session\\AbstractSessionStorageBackend->update()
#2 [internal function]: osTicket\\Session\\AbstractSessionHandler->write()
#3 [internal function]: session_write_close()
This addresses an issue where using the `Does Not Have A Value` criteria
on things like Short Answer Fields shows incorrect results. In fact, it
shows all Tickets with and without values for the Field. This is due to
using an overall negative filter (`column IS NULL` or `NOT column IS NOT
NULL`) on a column from a LEFT JOIN causing the backend to return NULL
for all values in that column. This adds a new variable called
`$nullable` that is set to `false` if the `$method` is `nset`. This then
passes `$nullable` to `getOrmPath()` so it can determine wether or not
to force a normal JOIN instead of LEFT JOIN so that `xxx IS NULL`/`NOT
xxx IS NOT NULL` will return the proper results. If the search method is
not `nset` then it will use LEFT JOIN as before.
This addresses an issue where when a Queue is filtering by a specific
field the counts are incorrect. This is due to using only the
`constraints` instead of both `constraints` and `path_constraints`. This
updates the `counts()` method to include the `path_constraints` if set
so that the counts are properly calculated.
This addresses an issue where Users login, do something, and get
randomly shown the login screen. If they refresh the page it shows
them authenticated as normal again. This is due to a Session ID mismatch
in `isvalidSession()`. When `refreshSession()` calls
`regenerateSession()` it's supposed regenerate the session and update
the session ID however it updates the local ID which `refreshSession()`
later does. This updates `regenerateSession()` to where it updates the
session ID and allows `refreshSession()` to update the local ID. This
deduplicates the local ID update and corrects the ID mismatch.
This addresses an issue where Disabled Queues are still being used in
counts. This is due to grabbing any CustomQueue that has the
`FLAG_QUEUE` flag and/or having `staff_id` equal to the current Staff
member's ID. This adds another filter `Q::not(…'flags__hasbit' =>
CustomQueue::FLAG_DISABLED,` that will ensure the Queue is not Disabled
before using in counts.
This addresses an issue reported on the Forum where when a field is set
to not visible to Users it is hidden from the Staff Ticket Print PDF.
This is due to the ThreadEvent MODE that is being used (MODE_CLIENT).
This uses the User Ticket Print template instead of the Staff Ticket
Print template which hides some thread events and other data. This
updates the utilized MODE to MODE_STAFF so that the appropriate data is
printed. This also addresses an issue where if the Staff has Relative
time configured it shows in the Ticket Print which should not happen.
This adds a check for `$_REQUEST['a']` and if it's set we make sure it’s
not `print` to avoid printing relative times.
This addresses a small logic issue where we are adding Public and
Featured FAQs in the Featured sidebar when it should only be Featured
ones. This updates the ORM statement to only show FAQs that are set to
Featured and belong to a Public or Featured Category.
This addresses an issue where emails being rejected by Banlist is
causing excessive processing errors and refuses to move the mail. This
is due to our logic expecting `403` exception code for TicketDenied but
we are using `500` in `TicketApiController::createTicket()`. This
updates the `exerr()` line to use the `$errors['errno']` if it exists
otherwise default to `500`.
This addresses an issue where printing a Ticket with Tasks or printing a
Task itself will throw a fatal error of `Non-static method
DynamicFormEntry::forTask() cannot be called statically`. This updates
the `forTask()` method to be static to avoid fatal errors.
This addresses an issue where if you have more than one instance of LDAP
plugin enabled and try to lookup a User it fails with a fatal error of
`Object of class StaffLDAPAuthentication could not be converted to
string`. This is due to using `array_unique()` which can't convert
objects to strings. This updates the method and adds the `SORT_REGULAR`
flag so that it can compare without converting objects to strings.
In addition this addresses an issue where we were using static ID for
StaffLDAPAuthentication backend. We updated the plugin code to reflect
the actual Backend ID but the current AJAX regex for this doesn’t match
this format. This updates the AJAX regex to match the updated format.
When fetching a mailbox, osTicket routes fetched emails to a department based
on `To` or `Delivered-To` header entries. This allows for ability to fetch
aliased emails from one primary account and route them based on configured
system emails. On failure to match, the email (ticket) is routed to the
department of the email account being fetched.
With the email backend overhaul in v1.17 - a bug was instroduced where
unmatched emails ended up being routed to default department instead of the
department of the email being fetched.
This commit addresses the issue...
When running osTicket in a multi-node cluster setup, it makes sense to connect
to the database via a load balancer or a database proxy (assuming VIP with
failover support). It's great for redundancy - however - this adds extra time
(miliseconds) because of the extra network hop latency.
To save a few miliseconds - when osTicket (the Application) is also hosted on
the same node or container running the database proxy - then it might make
sense to attempt a local connection first before attempting via via the VIP
(sidecar pattern).
This commit adds multiple database hosts support, comma separated, when defining
DBHOST in osTicket config file (`ost-config.php`). It also adds a new _Database
Option_ to define `DBCONNECT_TIME` used to set `MYSQLI_OPT_CONNECT_TIMEOUT`.
Connection timeout is important with multiple hosts so connection attempts
(done sequencially) can timeout relatively quickly.
This addresses an issue where if a Collaborator views a Ticket via the
Check Ticket Status button in the Client Portal and then tries to repeat
the process with an additional Ticket it will redirect to login page.
This is due to when instantiating the session we use `$user->getId()`
which causes a problem when the User is a Collaborator. When
instantiating a session for a Collaborator object `getId()` returns the
Collaborator ID, not the Collaborator's User ID. This updates the call
from `getId()` to `getUserId()` which gets the correct User ID from the
Collaborator object (and others).
Prior to osTicket `v1.17.x` email fetching required and used php-imap module to
decode and parse emails, whereas locally or remotely piped emails (via API
endpoint) used a Raw Email Parser ("Mail Parser").
Using two separate backends meant duplicated code, logic and inconsistent email
processing.
Starting with osTicket `v1.17.0`, we overhauled the Email Backend to OAuth2
support and in the process we switched toxusing a unified Mail Parser for both
fetched and piped emails. To determined how the email got delivered in order to
handle errors for the interfaces accodingly, we relied on `PHP_SAP`I /
`php_sapi_name()`.
That was shortsighted because of the value of `PHP_SAPI` can be different in
the following cases;
1. Email Fetching can be triggered by autocron (Staff Activity) or by a remote
task (API)
2. `PHP_SAPI` cannot be relied on for php installations using php-fpm, php-cgi
or custom binaries for php CLI executable
3. Cron Job / Task entry "user-name" or "command path" might use separate php
executables (related to `#2`)
4. Triggering cron/php via php-fpm socket connection e.g using FastCGI Client
Since emails are fetched in batches - Email Fetching, unlike stateless API
requests, should be considered a CLI operation regardless of how it gets
trigerred, this necessary so the system can gracefully handle fetch and parse
errors.
This commit does just that and a few other minor logic / code cleanup.
~ Peter - with love!
To avoid session fixation, osTicket regenerates Session Id on-login and on
every session timeout set for the User/Agent even with activity.
This commit changes the logic to make sure that the regenerate `TIME BOMB` only
goes off on a GET request - this is necessary so we don't invalidate data
in-flight on a POST request since osTicket Forms API backend uses session_id to
generate form field names as well as CSRF token used on forms.
Emailed tickets skips user validation on purpose with the assumption that the
user has at least a valid email. The assumption can be problematic when
osTicket has issues parsing the from address due to invalid format.
To truly verify an email, osTicket uses DNS lookup by checking MX record, if
that fails it defaults to checking A / AAAA record of the email domain.
This commit handle a case where a domain doesn't have A record.
This commit adds ability to ask backend to destroy a session by session_id.
Also changes how expire routine works - passing zero ttl results in the session
being destroyed immediately.
This mitigates a vulnerability reported by legoclones on
[huntr.dev](https://huntr.dev/) where XSS can be stored/executed via a
User's `username`. If an Agent is redirected to the User Lookup AJAX
response directly it will execute the stored XSS. This adds
`Format::sanitize()` to the `username` before saving to the database so any
potential XSS is sanitized. Additionally, this adds `Format::htmlchars()` to
the `username` before displaying in the UI to help prevent code execution.
This initially targeted a particular vulnerability with the Advanced
Search Refresh URLs but subsequently evolved into unifying all Refresh
URLs. We decided to create methods that properly encode URLs to prevent
code execution and to ensure they are all uniformly created. This adds
such capabilities and updates current Refresh URL generation to the new
methods. This also adds a method `Format::http_query_string()` that will
filter the query string and remove any unwanted params. Lastly, this
removes the old and tired `Misc::currentURL()` in favor of the new
"hip" (is that what the kids say these days?) method `Http::url()`.
Skip validating the structure of email request - this is important since emails
don't necessarily have all User Information - e.g name and should be failure
resistant.
On mail parse error, osTicket typically leaves the email alone and reports it
as a fetch failure - which results in multiple fetch attempts until an admin
manually moves the email out of the Fetch Folder. Most parse errors are caused
by poorly formatted mime message (email) that failes to decode.
This commit adds ability to create a ticket even when osTicket encounters mail
parse error. The entire raw email is attached to the ticket as message/rfc822
(.eml) attachment.
As part of post-processing options, when fetching emails, osTicket can archive
(move) or delete (remove) a mail message from the server. When using mail
storage backend like IMAP - both operations requires `expunge` command to truly
commit the changes to the mail server.
That's all good and well, except Laminas Mail (our darling upstream lib)
expunges the mailbox in real-time when a message is moved or deleted. This
creates a problem for osTicket because **expunging causes message sequence
numbers to reset at the server end during the session!!** Which in turn causes
mismatch when we process the next message in the queued sequence. Additionally,
expunging on every message operation cases unnecessary traffic to the mail
server when every second counts.
To resolve the issue - until we switch to using `UIDs` - this commit simply
bypasses Laminas Mail IMAP's removeMessage function so we can skip expunging on
message move/remove operations. osTicket expunges the mailbox at the end of
fetch session.
This commit removes "to" and "subject" headers before headers are prepared and
passed to MTA. It's necessary since the headers in question are set directly
via PHP mail() function - leaving them results in duplicate headers.
This is a temp fix needed for Windows installs until we upgrade to the latest
version of Laminas Mail which already has the fix. The version we use currently
doesn't strip the headers on Windows.
This addresses a small typo (6351) where `l` was being added to each
email string for the Default MTA setting. This removes the `l` so the
emails are displayed properly.
This commit attempts to avoid errors / exceptions that cannot be managed from PHP
userspace when an SMTP object is destructed. It also adds a connection timeout
of 5 minutes so old connections can be recreated.
This addresses an issue where if the Issue Details field or any custom
FileUpload field don't have `configuration` set any file upload to such
fields will fail with `File too large` error. This is due to the
`configuration` not being set so when we check the uploaded file size to
the allowed file `size` from the field's config via `$config['size']` it
fails. This adds a check for the `size` option in the `$config` array
and if not set or set to NULL then we will default to the system setting
`Agent Maximum File Size`.
This addresses an issue where there may be no `$ticket` available which
makes the `checkStaffPerm()` check fatally fail. This adds a check for
`$ticket` before checking the permissions. If no Ticket exists then we
set `Access Denied` error.
As the name suggests this converts the `FileUploadField::isValidFile()`
method to static. This also updates the relevant calls to static format.
Lastly, this removes the check for `function_exists('exif_imagetype')` as we
now define this if it doesn't exist.
This adds a minor improvement to the `Format::searchable()` method by adding
a new param called `$length` that will allow you to pass in a specific
length to ensure the text is less than or equal to the supplied length. If
the text length is greater than the supplied length then it will return
`NULL` (ie. not searchable).
This addresses an issue where some emails contain CSS `position` attributes
that can royally mess up the Ticket View. This adds REGEX to the
`Format::safe_html()` method that will remove any `position` attributes to
avoid rendering issues. This also adds a `position` attribute to the Thread
Entry div to ensure proper rendering.
This addresses an issue where some emails have malformed headers like `From:
"User Name" <email@domain.tld` which causes issues when processing.
This adds a check for malformed headers and if malformed then it will fixup
the header to prevent processing issues.
This addresses an issue where when validating a SelectionField's typeahead
value if there is no `$entry` the check will fail. This ensures `$entry`
exists and is set before using it in the subsequent checks.
osTicket currently fetches messages in LIFO order meaning the most recent messages get
fetched first. This was intentional to avoid possible stalemate when fetched
messages are left in the inbox (Do Nothing Option). However, this can creates
out of order threading issues since subsequest replies can be fetched first.
This commits addresses the issue by changing the logic so we can fetch older
messages first (FIFO order) as long as the numbers of the emails in the folder
being fetched are less than maximum messages to process at a time.
This commit makes sure we're returning the correct result (boolean) when moving
a message. Laminas Mail (upstream) doesn't return a value when moving a message
- success is assumed unless we catch an exception.
This commit adds a try/catch to catch possible exceptions that might happen
post ticket create. This is necessary so we can isolate problematic emails from
segfaulting the entire process (fatal error) or cause it to skip expunging the
mailbox.
The commit also adds debug logging for such errors / exceptions.
This addresses an issue where if someone doesn't install the PHP `exif`
extension, subsequent calls to `exif_imagetype()` returns `undefined`
errors. This checks to see if the method is defined and if not defines it.
This commit addresses an issue where we mistakenly disabled email account
status when upgrading to 1.17.x from older versions.
The change makes sure the status is maintained based on what's set on
hashtable.
This commit adds ability for session backends to report on certain events,
allowing us to keep app logic out of the session library.
The only event supported at the moment is "onClose" - triggered right before
the session commits the session data.
osTicket renegerates session id 10 seconds after login and that's it. This
commit add a timer to regenerate session id based on user's set max idle timeout
regardless of activity. If session timeout is disabled then it defaults to
every 24 hrs.
This addresses an issue where if using a webserver that encodes URLs by
default (like NGINX) some of the AJAX URLs will not resolve. This
ensures the URL is decoded with `urldecode()` before matching and
dispatching.
This addresses an issue where the Audit Log plugin shows Ticket Views in
the Audit Logs and shows the setting as enabled even when you disable
and save via plugin config. This is due to the current
`Config::exists()` method using the config `->get()` method and checking
the return value to determine `true` or `false`. This is problematic,
especially when values can be `NULL` or `0`. This updates the
`Config::exists()` method to check if the key exists in the session, in
the config array, or in the defaults. If the key does exist then we
return `true` otherwise we return `false`.
This commit should have probably been broken into smaller commits but the
wholesale change was required since it's an overhaul of how osTicket handles
sessions.
This addresses an issue where Information and SectionBreak Fields do not
display on Ticket edit for Users and Agents. This is due to no
visibility option for Editable for these field types. Since these field
types don't have Editable visibility when we check for
`isEditableTo[Staff|Users]()` it returns false. This overwrites the two
methods for both field types so that they are visible on Edit if the
field is visible to the respective user-type (User/Agent).
This addresses a small issue where Favicons weren't appearing on the
Staff Login Page. This is due to the Staff Login Page using a different
header than other pages. This adds the Favicons to the Staff Login Page
Headers so that they appear correctly.
This addresses a small issue where we were calling `setTimestamp()`
instead of `getTimestamp()` which causes a Fatal Error. We didn't notice
this in previous versions due to pre-PHP 8 it was only a Warning not a
Fatal Error. This updates the line to call the correct method which
avoids any fatal errors.
When we do $thisstaff->getDeptAgents, we are trying to get active agents $thisstaff can assign tickets to. The query done for this groups records in the staff_dept_access table by staff_id, so when we try to do getRoles() for $thisstaff, the only role we can get from staff_dept_access is the first record for $thisstaff.
This commit unsets the dept_access relation so that it can be requeried to get all staff_dept_access records for $thisstaff.
This commit centralizes sessions init by defering it to Bootstrap:ini() -
when setup scripts needs to start an independent session (e.g cli installer)
Centralized session init is also important because, going forward, it will make it
easy to make changes in one place e.g when changing error_reporting setting
application-wide.
This commit centralizes sessions init by defering it to Bootstrap:ini() -
when setup scripts needs to start an independent session (e.g cli installer)
Centralized session init is also important because, going forward, it will make it
easy to make changes in one place e.g when changing error_reporting setting
application-wide.
osTicket support uploading your own logos as well as login backgrounds and
calls logo.php (on both panels) to fetch the image in question. Previously we
didn't care about session data so session handler was set to an inline noop
function as a way to bypass starting a "real" session. The problem with the
approach is; if osTicket is hosted behind a proxy with multiple web severs in the backend,
the proxy needs to send all requests to the same server for specific user
session. To do so session name (OSTSESSID) is used to route requests from the same session
to the same backend server.
This commit adds a noop session backend allowing us to start a session while
still ignoring data writes. Noop backend is used when DISABLE_SESSION is
defined and set to false.
This commit adds a check to make sure an Email Account has valid credentials
when determining if the account is active. It's necessary so we can detect
deleted credentials or expired refresh token in the case of accounts with
oauth2 backends.
This commit addresses an issue where outgoing email can get rejected when the
target mail server is tight-assed - requiring a valid host when saying
helo/ehlo.
We were setting the name to null which resulted in localhost being used as the
name. Now we're asking the OS to give us the proper hostname of the server -
hopefully the server admin has the correct hostname and reverse-lookup setup
correctly for better deliverability.
When configuring an email, starting with osTicket v1.17, the adminstrator can
hint to the desired encryption when using non-stantard ports by prefixing the
`hostname` with an encryption scheme e.g `tls://` or `ssl://`. Using hints is
much better and less confusing than the old ways of presenting a user with
`IMAP` and `IMAP + SSL` as protocol selections - when infact we could use the
port number, in the backend, to determined the encryption.
This commit adds support for the opposite - by allowing an admin to force
unencrypted connection even when using standard encryption ports by simply
adding `plain://` as the scheme hint.
This commit adds a routine to get Message-Id and also adds a check for an
invalid Id when trying to set a Message Id.
Please note that invalid ID are silently ignored since the upstram library
generates one.
Spoofing: When an SMTP Account **DOES NOT** allow spoofing then set the Sender
(Envelope FROM) to the account's email address and leave the Header FROM as
set
Originator: When an SMTP account send fails - we now reset the Originator /
Sender to the original From Address, incase spoofing setting changed the
Sender
* Spoofing - when an SMTP Account does NOT allow spoofing then set the Sender
(Envelope FROM) to the account address and leave the Header FROM as set.
* SetOrinator - When an SMTP send mails we now reset the Originator / Sender to the original
From Address just incase spoofing setting had changed the Sender.
First error: abstract functions can not be private. It have to be protected or public...
Second error: the pop3 login function doesn't respond anything on successful login. This will be return false in MailBoxProtocolTrait::basicAuth()
Message-Id: osTicket uses encoded message Id to thread emails on reply.
Laminas Mail, the new backend we're mangles up the Message-Id when set as a
generic header. This commits corrects the issue by using MessageId object -
making sure it is ASCII encoded.
Date: Date is auto-added upstream - so we're removing it from Mailer to
avoid double header issues - but if need be, you can overwrite it by setting
your own fake date!
This addresses issue 6291 where importing users from CSV via command
line causes a fatal error. This is due to attempting `fclose()` on a
stream that has already been closed. The CsvImporter `__descontruct()`
method already closes the stream so when we get to the end of the import
and attempt to call `fclose()` in the CLI method, it causes a fatal
error as the stream is no longer valid (as it's already been closed).
This adds a check to see if the stream is a valid resource and if so
then we close it, otherwise we skip and continue (as it's already
closed).
This commit addresses backward compatibility issue related to the data sent to
pre_save hook. Older plugins expected clean data whereas the new interface
provided to_db data which might be json formatted for example depending on the
config field database format. Now we will send the clean data to pre_save then
transform the results for database storage via the form / fields.
This commit is a temporary fix for possible Fatal Crash when file key (hash
lookup) matches more than one object on lookup. See TODO note for more
information.
This addresses an issue where if `imagecreatefromstring()` fails it
returns false (boolean) and we then pass that to `imagesx()`. This
method only accepts Gdimage (since PHP 8) so this adds a check to see if
`$image` can be set and if so we continue otherwise we skip the `if()`
completely and go straight to sending the data.
This addresses an issue where password reset is triggered even though the
user/agent doesn’t have a password or the authentication backend is
external.
This commit fixes a bug where getNotice was undefined when rendering a dynamic
form entry. It now delegates getting a notice, if any, from the form impl.
This commit adds ability to log email parse errors. This can happen if the
system fails to fetch complete raw email or when the email content is malformed
somehow.
Log last fetch timestamp on login and before processing emails so that the
mailbox can yield to other mailboxes in the fetch queue.
Also catch Throwables instead of just Exceptions
Catch possible throwables (Exceptions and Errors) from file storage backends.
This is necessary so we don't crash while trying to save a file when storage
backend is having issues or bugs. osTicket uses database as fallback storage.
This commit refactors how FROM address is set and used within the Mailer. It's
now set as EmailAddress object - making it easy to get Email and Name
separately.
We're also removing Spoofing Check when determining possible SMTP accounts to
use for outgoing emails. It's now checked while attempting to send a Message.
If the account in question doesn't allow Spoofing then the FROM header is reset
to the accounts email address.
This commit adds ability for Mailer to skip invalid email recipients when
sending out an email. A Mailer warning with the recipient info (name & email
address) is logged.
For uniformity sake EmailContact interface now requires getEmailAddress() to be
defined downstream. This was necessary because some of the objects (e.g Staff)
return a name when casted to string (__toString) and changing it will affect
variables used in email templates and possibly leak the agents email.
This addresses an issue where a wrong variable was used which caused
undefined variable errors with the built-in tests. This corrects the
variable from `$sql` to `$exec->sql`.
This addresses an issue where we were not renewing the cookie expired
time correctly when refreshing the session. This updates
`refreshSession()` to accept a `$refreshRate` defaulting to 60
(seconds). This also updates the `if()` statement from a negative to a
postive logic for better readability.
Some Plugins DO NOT or SHOULDN'T support multiple instances due design issues
or simply because of the fact that it doesn't make sense to do so.
The blacklist will be removed down the road once plugins are forced to declare
compatiple core osTicket version and if it supports multiple instances.
This adds ability and interface to auto-trigger plugins upgrade or downgrade
when there's a version mismatch on-load.
The base plugin class simply updates the version (for now) - the downstream
Plugins should implement the actual upgrade / downgrade process as needed,
especially if it creates database tables or needs to change stored config info
to match the new version format.
This addresses session issues when upgrading from versions pre-1.7. This
bypasses the DBSessionBackend if `MAJOR_VERSION` is not defined or an
upgrade is pending and the `getDBVersion()` method returns `true` to
default to using the local session storage.
This commits sets UTF-8 as the default encoding. It's necessary because - by
default Laminas Mail uses ASCII encoding - which can cause `invalid header
value` exception when an email address of the sender or a recipient has an
accented character.
Please note that individual Mine Parts set thier own encoding as needed - by
default osTicket uses base64 to encode `text/{plain/html}` parts to reduce the
overrall size of the Message - configuratable option to make `quoted-printable`
encoding an option is planned.
This commit addresses a bug where the new Mail Fetcher failed to handle Denied
Tickets (via banlist/filter) correctly. In addition, email parsing is now
delagated to Mail Parser utility class.
This commit addresees an issue where mail fetcher crashed when logging a
warning on excessive fetch errors. As part of the fix, Email AccountSetting is
now the single source of truth when it comes to Email Account information.
This addresses issue 6218 where using `include` for things like
`api.tickets.php` fails with fatal error of `Cannot declare class xxx,
becuase the name is already in use`. This changes `include` to
`include_once` so that we avoid fatal errors and the files still get
included.
This addresses some various Upgrader issues when attempting to upgrade
from an older version (eg. `v1.6` and `v1.7`). This includes catching
more exception types, making a method static, adding some variable
checks before calling `count()`, checking for session ID before setting
custom handlers in the session class, and last (but not least) a
try-catch statement around `$__db->query()` calls so that we can catch
Excpetions without exiting.
This fixes the Deprecation warnings when attempting to set INI directive
`ini_set('auto_detect_line_endings', true)`. This directive is no longer
supported so this removes the calls completely.
This addresses the Deprecation warnings when attempting to implement the
Serializable interface without defining the `__serialize()` and
`__unserialize()` methods. This updates the code for each class that
implements Serializable to define these methods and to call the original
methods we have.
This commit fixes an issue where some default data was not being inserted into the database for fresh installs:
1. Sales Department
The Sales Department was not being created because we were trying to set an sla_id before the SLA table was created.
2. Banlist
The default Filter Rule and Action for the System Banlist was not being created because the save function now calls the ORM save function, so it is no longer calling save_rules and save_actions for the installer. We also have to change the YAML to refer to the fields as w,h,v instead of what, how, value for them to be recognized correctly.
It also fixes some spacing issues in the Filter class.
This commit addresses an issue where Password Policy Plugin crashed on login
when password expiration is set to "Never Expire" and php mode set to strict.
This is because v1.17 changed how plugin instances config values are stored to match
the actual field format (using to_db), but on load - PluginConfig mistakenly
defaulted to database value when to_php returned an empty value - which is
indeed correct value when selection was empty option.
This is necessary to allow plugin instances to use different config forms as
desired depending on internal logic. For example OAuth2 plugin can have both
Authentication and Authorization instances which require slightly diffrent
fields and validation.
This commit adds ability to inject and display a warning message on dynamically
rendered forms. This is helpful when various components want to add such
warnings while not having full control of the display logic.
This updates the ticket search mechanism to check if the supplied keyword is
a number. If the keyword is a number we will only search Ticket Numbers to
improve search performance.
This addresses an issue where we are rotating the session on each login
to help prevent session fixation. However, this causes an issue when
using an External Authentication Backend such as OAuth2. This remove the
`regenerateSession()` calls from the `login()` methods and instead we
will set a time bomb that will auto regenerate the session a certain
amount of time after login. This way external auth backends will still
function properly and we can still regenerate the session.
This addresses an issue where we are not checking the Field Variable
Names with case-insensitive comparison. This causes issues as the
database doesn't care about case and sees the two variables as the same.
This hardens our variable name checks to convert existing names and the
new name(s) to lowercase for case-insensitve comparison. With this
change it will no longer allow duplicate variable names (with a
difference of case).
This addresses an issue where the Audit Plugin relies on `enable()`
being called in order to create the `_audit` table required for saving
audit data to the database. This adds the method back temporarily until
we can rewrite the plugin to fit the new standards. This also attempts
to call `enable()` on install so that the table can be created. If the
plugin doesn't have an `enable()` method it defaults to the parent class
Plugin `enable()` which just returns `true`.
This addresses an issue where we are not regenerating the session for
Staff members after they've opened a Ticket. This adds
`$thisstaff->regenerateSession()` after creating a Ticket so that the
session is regenerated.
This addresses an issue where we are calling `getId()` instead of
`getBkId()` in some places when registering and listing plugin instances. This causes
an issue if a User is auto-created via something like LDAP and the
`backend` is set to something like `ldap.client.p[id]i[id]`. When we get
available/registered backends we are not selecting the appropriate ID so
the backend is considered "not in the list" and does not let the User
authenticate. This changes all the calls to `getBkId()` to ensure we are
selecting the appropriate ID.
This addresses an issue with PHP 8.1 where on install we run a query to
see if we can select data from the ost_config table to see if there is
already an instance installed to avoid overwriting data. In PHP 8.1 this
will throw a fatal error which kills the installer. This adds a `try {}
catch() {}` statement around the call so that if it does throw an error
it continues without issues. This is what we want anyways, if the query
returns false or an error then we want to continue.
This addresses an issue where some emails don't have a To header which
causes a fatal error when parsing mail. This is due to assuming To is set
and passing it to array_unique which expects the value to be an array. This
adds a check to see if To is set and if so we call array_unique otherwise we
default to an empty array.
This addresses an issue where updating the Queue Export Column Headings
doesn't actually save the changes. This is due to using the previous heading
regardless of the headings being passed in. This adds a check for the column
heading in `$fields` and if exists we use that otherwise we default back to
the previous heading.
This commit addresses an issue where the plugin cached the config of the first
instance loaded. The change delegates config loading to the instance when side
loading on bootstrap.
With the config moved to central config it's necessary to sort, platten the
array to json before getting md5 value.
Signature is used to detect configuratuion changes.
This is necessary for fields that chance e.g PasswordField getting decrypted.
Using upstream config store can result in decoded/decrypted values being saved
by mistake.
This addresses issue 6197 where setting Help Topics sort to Manually throws
a fatal error. This is due to not checking if `$_POST['ids']` is an array
before passing it to `array_intersect()`. This adds a check to see if the
ids are an array and if not then `$diff` will be set to an empty array
(which is what `array_intersect()` returns if the arrays have no common
values).
This is useful to plugins looking for triggered backend.
This commit also adds 'id' to Auth Strike backends - needed to be successfully registered them.
This commit adds osTicket version compatibility check to plugins.
Plugins can now indicate required version of core osTicket by specifying
`ost_version` in plugin.php file.
This improves Email searching on full search. This ensures the search query
is emailish and if so searches only user emails. This improves sql query
execution time.
This addresses an issue discovered by the AppSec Research Team at Checkmarx
where the `action` attribute passes through sanitization successfully which
can be potentially harmful. In addition `<form>`, `<input>`, and `<button>`
elements can be maliciously crafted. This updates the htmLawed configuration
to deny the `action` attribute in all elements as well as denies all
`<form>`, `<input>`, and `<button>` elements.
This commit addresses possible session fixation on both agent and end user
login. Upon login users are now issued new session with the old one
invalidated.
This mitigates a vulnerability discovered by the AppSec Research Team at
Checkmarx where it's possible to update your Agent password without passing
a valid current password. This adds a check to compare the provided current
password with the actual current password to ensure they match. If they do
not match an error will be returned stating `Current password is
incorrect.`.
This mitigates a vulnerability discovered by the AppSec Research Team at
Checkmarx where it's possible to perform Stored XSS via invalid CSRF tokens
in the System Logs. This is due to not properly sanitizing the CSRF content
before saving to the database as well as not properly escaping the content
before displaying in the UI. This adds `Format::sanitize()` to the content
before saving to the database as well as `Format::htmlchars()` before
displaying.
This mitigates a vulnerability discovered by the AppSec Research Team at
Checkmarx where it's possible to perform Reflected XSS in the Agent
Directory. This was due to the `order` and `sort` URL params not being
properly escaped. This adds `Format::htmlchars()` to both params to ensure
they are properly escaped.
This is a rewrite of 6163 where we aren’t checking User/Agent status on
login and on session validation. This adds checks to the
UserAuthenticationBackend to ensure the User is active (ie. confirmed and
not administratively locked). This also adds checks to the
StaffAuthentciationBackend to ensure the Agent is active (ie. not locked).
If a User/Agent is not active they will be redirected to the login screen.
This addresses an issue where installing `1.16.x` has the Ticket Details
Form Fields disabled for every Help Topic. This is due to checking if the
Field IDs are in an empty array which obviously will return false. This
updates the declaration of `$fields` from `array()` to `null` if the array
index doesn’t exist. This also updates the `if` statement for the Field ID
checking to ensure the `$fields` variable is an array. This ensures that the
check is skipped if `$fields` is `null` avoiding erroneous disabled fields.
This addresses an issue where removing all text in Redactor in the Post
Reply box freezes the entire page (using 90% or more CPU). As a quick
workaround user jarnott from the Forum found that adding a `br` tag
between the `draft_id` input and the Post Reply `textarea` fixes the
issue. This adds the `br` tag to temporarily address the issue until
Redactor addresses the issue permanently.
This addresses issue 6159 where tables are not appearing correctly in PDFs.
This is due to mPDF config revert when upgrading mPDF. This updates the
config `ignore_table_widths` to `true` so tables appear correctly.
This commit fixes an issue where we were only filtering out Private Departments from the Primary Department options for Agents when we should have been filtering out the Disabled and Archived Departments as well. This allowed trying to save an archived/disabled Department as the Agent's primary Department which threw an error.
Another issue was that if there was an error on dept_id, we didn't display the specific error message under the field, so you wouldn't know what to correct. Additionally, the error message for role_id was under the 'Fall back to primary role' checkbox instead of the Role field.
This problem was discovered through Issue #6135
This is a rewrite of pull 6123 where it adds translation support for client
side queue column sort tooltips. This breaks apart the tooltip strings into
two parts allowing `Sort By` and the column name to be translated
separately.
This addresses an issue reported on the Forum where Fields are not honoring
the Length value. This is due to the label being set to `length` while the HTML
attribute is named `maxlength`. This adds a case for `length` that sets the
attribute name to `maxlength`.
This addresses an issue where the created date for banlist items show an
old, incorrect date. This is due to not setting a created date before saving
to the database.
This addresses an issue where starting with PHP 8.0 the `date()` method
changed the `timestamp` parameter to be nullable. If the `timestamp` is
`NULL` then it will return the output from the `time()` method. So instead
of returning a default date of `1970-01-01T00:00:00+00:00` like it used to
it returns the current date. This is obviously a problem when it comes to
datetime based Queue Columns like Last Response with no value. Since there
is no value it gets translated to the current time and displays `just now`
in the columns instead of a blank column. This updates the `date()` call to
use `0` if the `timestamp` is `NULL` so that it returns the default datetime
of `1970-01-01T00:00:00+00:00` essentially restoring previous behavior.
This addresses issue 6079 where using `1.16.x` and PHP 8.0 on certain GNU
systems (eg. Alpine, Solaris, etc.) throws a fatal error of `Undefined
constant: "GLOB_BRACE"` when loading Plugins. This is due to `GLOB_BRACE`
not being available on said GNU systems. This removes `GLOB_BRACE` from
`include/class.plugin.php` completely as it is not used anyways.
This addresses an issue reported on the Forum where the Last Message and
Last Response Data Sources are not showing the correct times. This is due to
an erroneous change made to support PHP 8.0. We added `isset()` to parts
where we are selecting array keys but didn’t add a check for the value. This
adds checks for the values to ensure we are continuing at the appropriate
times.
This addresses issue 6059 where Ticket Filter processing stops accurately
but the Thread Events are blindly added for any Filters that match the
criteria. This is due to not checking the current Filter in the iteration
for `stopOnMatch()`. This adds a check for `stopOnMatch()` and if `true` we
will break the loop.
This addresses an issue reported on the Forum where when
`Mail::parseRecipients()` is called it throws a fatal error of `Uncaught
ValueError: mb_convert_encoding(): Argument #2 ($to_encoding) must be a
valid encoding, "localhost" given`. This is due to an erroneous change when
adding PHP 8.0 support. We changed the called class from `Mail_RFC822` to
`Mail_Parse` but left the same arguments. This is obviously an issue as both
classes' methods take different arguments. This changes the called class
back to `Mail_RFC822` to stick to original functionality and updates it for
PHP 8.0 standards.
This addresses an issue reported on the Forum where exporting Tasks gives
you a fatal error. This is due to not checking if `$current` is set before
using it in `method_exists()`. This checks to make sure we have `$current`
set before using it.
This addresses an issue reported on the Forum where when adding a new Queue
Sort an error of `Uncaught TypeError: count(): Argument #1 ($value) must be
of type Countable|array, string given` is thrown. This is due to passing the
wrong arguments to the `QueueSort::update()` method. This corrects the
arguments to `$vars, $errors` to resolve the error.
This addresses an issue where when running cli tests a validation check for
`jared@` failed. This is due to switching the calling class of
`parseAddressList()` from `Mail_RFC822` to `Mail_Parse`. This reverts the
calling class to `Mail_RFC822` to fix the issue.
This addresses an issue found when running cli tests where two static
methods are using `$this`. This updates the methods to remove the use of
`$this` and updates remaining non-static calls to static.
This addresses a few issues reported on the Forum where some methods are
throwing `Deprecated: required parameter follows optional parameter` errors.
This updates the erroneous methods to match the PHP 8 standards using
explicit nullable types with defaults.
This addresses an issue where in PHP 8 you can no longer pass variables by
reference to preg_match. This moves the definition of the variable outside
the preg_match so it no longer complains.
This addresses an issue reported on the Forum where a couple of `each()`
methods slipped through the cracks. This updates all the `each()` (minus the
php_analyzer file for now) to the new PHP 8 standards.
This addresses issue 6074 where `sendUnlockEmail()` is static but cannot be
as it uses `$this`. This updates the method to non-static and updates all
calls to non-static calls.
This addresses an issue where `Auth_SASL::factory()` is being called
statically but is not static. This updates the method to static so it can be
called statically with no issues.
This addresses an issue where `Banlist::add()` and `Banlist::remove()` are
non-static methods that are being called statically. This updates the
methods to static so that they can be called statically.
This addresses an issue reported on the Forum where cloning a Template Set
gives you a fatal error of `Non-static method EmailTemplateGroup::add()
cannot be called statically`. This updates the `add()` method to static for
`EmailTemplateGroup` and `EmailTemplate` classes.
This addresses issue 6063 where TicketStatusList does not have a
`getSortModes()` method and fatal fails when loading the status list. This
was done by `__call()` via `CustomListHandler` previously but we changed
`getSortModes()` to a static method to match PHP 8 standards. We didn't
account for the fact that `__call()` cannot call a static method as it uses
`$this` context. This renames the `getSortModes()` method for `DynamicList`
to `sortModes()`, creates a new method called `getSortModes()` which returns
the self `sortModes()`, updates `dynamic-list.inc.php` to call the method
non-statically and for `DynamicList` calls `sortModes()` statically, and
removes `static` keyword from `getSortModes()` on `CustomList` interface.
This addresses a lingering `each()` error with the PEAR library. This
updates the `while(list() = each())` statement to a simple `foreach()` to
get rid of the error.
This includes further miscellaneous fixes found while running through a
basic installation. This includes calling non-static statically changes,
parameter must be of type array changes, and class not found changes.
This includes even more miscellaneous fixes found while adding PHP 8
support. This includes incorrect capitalization of a class name and removing
unnecessary include statements.
This addresses issue 6031 where the Khmer Language Flag is inaccurate. This
updates the `css/flags.css` file to adjust the pixel frame for
`.flag.flag-km`.
This addresses an issue where you cannot save a value for an Assignee field
that’s in the Item Properties of a List Item. This is due to the method used
to prepare the data for the backend as well as the format of the data when
returned from `to_database()`. This updates `to_php()` to `to_database()` to
get the appropriate data for the backend. This also updates `to_database()`
to return the JSON encoded data itself instead of in an array. Lastly, this
updates the `getChanges()` method to remove the need to account for an
array.
This addresses issues 6043 and 6053 where installing osTicket and doing a
User lookup will return a fatal error of `Unknown column 'A5.phone' in
'where clause'`. This is an indirect result of the changes we did to rebuild
CDATA tables post-installation. The issue is that we are using
`getInstance()` which returns a cached object. Changing this to always
return a new instance via `getNewInstance()` subsequently had issues with
the TicketForm not adding the Priority field. We determined this is due to
object caching in the ORM so we added `ModelInstanceManager::flushCache()`
before we rebuild the CDATA tables to clear the object cache and prevent the
reuse of old objects.
This commit allows AuthBackends (e.g via SSO) to auto-register Users
even when the registration is set to private.
The rationale is - Users already in such backends like LDAP or SAML are
already approved/registered internally.
This commit fixes an issue where we were not deleting referrals when a Ticket was deleted. Now we will delete any referrals related to a thread when the thread is deleted.
When you don't use a "SLA Plan" the "Due Date" can be empty. The staff ticket view use now a "-Empty-" display value that the update popup link works.
It also fix a invalid syntax from the table cell.
This commit fixes an issue where we were double auditing the Closed event for Tickets. This should have been removed in PR #5051 in the 'Code Optimization' commit where we started automatically logging some of the audits in class.orm.php
This commit improves upon the feature by adding a 'getEventDescription' function to the 'TriggerAction' class so that we don't have to check to see if the method exists for the type of filter action.
It also ensures that an object is found that can be used within the Thread Event, and if we don't find one, we will just generalize the wording.
Ex:
Thread Event where name is found:
Set Department Filter set Department to Parent
Thread Event where Dept name is not found:
Set Department Filter set Department
This commit adds further detail to logging thread events for filters by creating a thread event for each filter action stating the filter, what it changed, and the value it was set to.
This commit adds a thread event to show which filters were applied to Tickets.
Note: If kept this way we would need a patch to update the event table and add the 'filter' event
This commit addresses an issue where CDATA tables got dynamically
created early in the install process, resulting in missing fields.
The change ensures CDATA tables (views) are rebuilt at the end of
install process.
This commit fixes an issue we had with forms that have been deleted that were attached to a Help Topic. If a custom form is attached to a help topic and then the form is deleted, we put a flag on the form so that existing tickets still show the fields. However, if you are creating new tickets with those help topics, the deleted form is still showing up even though it should be hidden.
A check has now been added in the getFormsForHelpTopic method to skip deleted forms when creating new Tickets.
The commit also updates the isDeletable to use the hasFlag function that was added.
This commit fixes an issue introducted by PR #5880 where we needed to split up the string of if statements checking the value and ids passed into to_php so that if we end up getting the id in one of the ifs above, we still do the priority lookup.
This addreses an issue in 3397987 where the upgrader attempts to create
cdata tables before Task form is loaded.
This commits moves the task to the end of upgrade process.
This commit addresses an issue where dynamic form field update can
trigger multiple cdata rebuld queries, resulting in database DOS or even
a cluster crash/lockup depending on the number of form entry entries.
The change makes it so CDATA tables rebuild is done on dynamic form
field update, instead of relying on users/agents to trigger the rebuild
process.
This commit fixes an issue where some template variables could not be used when using a Filter to send an email. The filter should run after the appropriate variables have been created in the ticket, and we need to set the recipient as the ticket owner within the filter action as well.
This commit fixes an issue where a DepartmentField or PriorityField added to a Custom Form would not show up in a
Queue Column.
PriorityField:
In to_php, if the $value passed in is actually the priority_id or the $id passed in is actually the priority_id, we should use the id to get the Priority value that should be displayed, however, if the $value passed in is already the Priority value as a string, we should return that value.
DepartmentField:
A display function needed to be added for this field. If the $dept passed in is the Department name, we should return that, otherwise if the $dept isn't a Dept object, we should use the parent display function as it was doing before. Finally, if the $dept is a Dept object, we should get the Department name from that.
This commit adds functionality that will allow us to use the attrs field in the file table to determine the file location being used for the S3 Pluign.
Credit goes to @protich
This commit fixes an issue with exporting Custom Department or Custom Assignee fields. In the exports, the fields were exporting as IDs instead of the actual field value.
Custom Department Field:
In from_query, if the value is just a dept_id instead of the department name, the field should pass the display function.
Custom Assignee Field:
- In to_php, we were missing logic needed to parse cdata into an array if the value was saved as 'id,value'
Ex: t34,Team1
First, we need to make sure not to accidentally clear out this value if the JsonDataParser doesn't work.
Next, this string needs to be set to an array like this in order to render properly:
['t34'] => 'Team1'
- If there is an Assigntee type, we should use substr to remove the letter from the array key in the event that the id for the field is more than one number
Ex: t34
The type should be 't' and the id should be 34.
Using key($value)[1] would set the id to just 3
- If the value coming into AssigneeField::to_php is the staff_id, meaning the value is just a number and we are not sending a type through, we should look up and return the Staff object.
This commit fixes an issue we had with list items that began or ended with a space. If the list was being used in a Typeahead or Input field, the values couldn't be selected if they didn't match with the spaces exactly. This commit strips the leading and trailing spaces before saving the list items.
This commit fixes an issue where unlinking all Tickets from a Parent Ticket did not remove the linked flag from the Parent Ticket which caused the Parent Ticket to show up in queues as still being Linked.
This addresses Issue #5811
This commit fixes an issue with checking on choices for the DepartmentChoiceField. We were setting $this->_choices to an empty array in the getQuickFilterChoices function, so when we did the check to see if choices were set or not, they were technically already set which resulted in the quick filters for the department field always showing as none.
This commit fixes an issue where we were not checking role permissions for inline edit on Tasks. If an Agent without the role permission to Transfer Tasks tried to click the Deparment to transfer it, it popped up a blank modal and said 'Permission Denied'. Now, the Department will not have the edit link if they don't have the permission.
This commit fixes an issue with how Departments and Agents show up in queue columns. If an Agent's Visibility was set to where they could only see Depts/Agents in a Department they have access to, it became an issue if the Agent was assigned a ticket in a Department they couldn't access (queue column would be blank) or if a Ticket was assigned to an Agent's Department but was assigned to an Agent that is not in any of the Agent's Departments (queue column would be the staff_id).
As long as an Agent has access to a Ticket, they should be able to see the value of the Dept/Agents related to that Ticket.
This commit cleans up the logic for how we use the getDepartments function. We should specify publiconly vs activeonly so that they can be used individually to specify which departments we want to get: publiconly, activeonly, or both as the criteria.
This addresses an issue where the system throws a fatal error of `Fatal
error: Uncaught Error: Call to a member function getDefaultDeptId() on null`
when doing a fresh installation. This was introduced with 5777 and is due to
trying get the default Department's ID from the system config when it's not
available. This adds a check for `$cfg` before calling it to ensure no fatal
errors are thrown.
This addresses an issue where choosing a Report Timeframe in the Dashboard
and clicking Refresh defaults the date to 2020 (yikes, please don't make us
relive it). In addition, the CSVs exported from the selected time periods
are blank. This is due to a date formatting issue in
`OverviewReport::getStartDate()`. This updates the replacement format from
`array('yy', 'yyyy', 'mm')` to `array('y', 'yy', 'mm')`.
This commit fixes an issue introduced with PR #5755 where we just echo the status of the Default Department so that you don't have the option to disable/archive it. When we update a Department, if $vars['flags'] isn't present, we clear out the flags to 0 and then set them according to the other vars set. Since we are just echoing the status name for the default department, $vars['status'] is NULL, so when you save the department, it ends up being disabled (we can't put the flag back). So if we're updating the default department, we need to confirm that it is the default and then manually set $vars['status'] to 'active' so that the flag is set correctly.
This addresses an issue where exporting large datasets (eg. 100,000+ Closed
Tickets) gives you a blank CSV once complete. This is due to PHP running out
of memory which results in no data being written to the CSV at all. This
sets the `QuerySet::OPT_NOCACHE` option to `true` so the result sets are
not stored in memory. Essentially, storing large result sets in memory is no
bueno.
This commit finishes fixing an issue we had with disabling or archiving a Department that is assigned to an Email. At one time, we were setting the Department in the Email to the default Department if an Email's Department was disabled or archived. Part of this was removed in #4588. If we are going to leave the Department in the Email, we need to make sure that Tickets fetched from that email are not assigned to the Disabled/Archived Department. This commit will check the deptId that comes in and if the Department is not active, the Ticket will be assigned to the default Department.
It also makes it so that you cannot change the status of the Default Department to Archived or Disabled. Rather than showing up as a selection, we will just show the Department's status.
This addresses a small issue where Agents were not sorted alphabetically
when Assigning/Re-Assigning a Ticket or Task. This is especially frustrating
when you have an enormous list of Agents. This adds `nsort()` to
`getDeptAgents()` so we can sort the Agents by the system's Name Format.
This commit adds to the latest database task. We need to see if the event table has the login, logout, message, and note events, and if a database does not, we need to add them to be used with the audit plugin.
This commit fixes an issue where the task needed in order to add the 2FA Email template to the database for upgrades was omitted from the codebase.
The new template needed to be added to fresh installs as well.
This fixes an issue introduced with the new Visibility Permissions. It did not account for the possibility that Users may be able to view a Custom Department field. In that event, we must make sure we can get active Departments that should show up as choices in custom Dept fields.
This commit makes sure that we have a clean array for filtered topics so that disabled/archived help topics are correctly handled in the returned selection.
This commit makes it so that FAQs that are associated with Help Topics that are associated with Departments an Agent does not have access to are hidden. It also ensures that an Agent cannot create an FAQ associated with a Help Topic that they do not have access to based on the Help Topic's Department.
This commit makes it so that Help Topics are hidden from the Agent Panel if they are assigned a Department an Agent does not have access to and the Agent does not have the 'Ability to see all Departments' permission checked.
If a Help Topic is Public, it will be shown in the Agent Panel.
If a Parent Help Topic is Private and assigned a Department an Agent does not have access to, we hide both the Parent and Children Help Topics.
If a Help Topic is not assigned a Department at all, it is shown throughout the Agent Panel.
Help Topics are filtered for:
- Inline Ticket Edit
- Ticket Edit
- Ticket Open
- Advanced Search
- Quick Filters
- Dashboard
This commit updates existing staff members so that they will still be able to see departments and agents within the agent panel the same way they are used to seeing them. This is done during the upgrade within a task.
This commit makes it so that the Agent and Department visibility permission is checked by default on fresh installs and newly created Agents unless otherwise specified.
This commit fixes an issue where quick filters for the AssigneeField class would not work because we were returning an array of AgentsName + Team name strings which did not sanitize correctly in htmlchars.
This commit gives us a way to determine if we should filter choices for setting field criteria. We need this to be optional because we use the same method for getting criteria choices in the Agent and Admin Panel, and for the Agent panel, we need to filter the choices based on the Agent's permission to view all Agents and Departments.
If Criteria are being set in the Admin Panel, all choices should be shown regardless of an Agents permissions.
filterVisibility needs to be applied for the following:
- AgentSelectionField
- DepartmentManagerSelectionField
- AssigneeChoiceField
- DepartmentField
- DepartmentChoiceField
This commit checks if the Agent has permission to see all Agents, and if they don't, only show Agents that are in Departments they have access to. This covers the following:
- Queue Assign Mass Process
- Ticket open Assign
- Ticket View assign
- Ticket Inline Edit Assign
- Ticket Refer
- Assigned Staff Quick Filter
- Assignee Quick Filter
- Department Manager Quick Filter
It also limits Agents shown in the Agent Directory based on the Agent permission checkbox as well as the Departments shown in the Department filter of the Agent Directory.
This commit fixes a bug where we did not accurately check individual Roles for Departments an Agent could access to determine if they could manage that particular Canned Response.
Now, we check to see if the Agent has a Role that can manage Canned Responses at all to determine if Canned Responses show up in the Knowledge Base.
Additionally, we filter Canned Responses shown based on the Role permissions of the Agent's Departments (Primary and Extended)
This commit allows us to determine if only public Departments should be returned or all Departments regardless of anything else. We need this for Agents that can see all Departments and search all Tickets
This commit checks to see if the Agent has permission to see all Departments, and if they don't, show only their Departments in forms that include a DepartmentField. This covers the following:
- Ticket Transfers
- Task Transfers
- Ticket Referrals
- Task Creation
Standard Forms:
- Ticket Creation
This commit adds the following checkboxes to Admin Panel | Agents | Choose an Agent | Permissions | Miscellaneous:
- Agent — Ability to see Agents in all Departments
- Department — Ability to see all Departments
This commit makes it so that Agents can only create Canned Responses for Departments they can access or Canned Responses that will show up for all Departments.
This commit filters Canned Responses so that Agents can only see Canned Responses for Departments they can access (Primary or Extended Access) or Canned Responses assigned to all Departments.
This addresses an issue where I forgot to recheck the hash after making
changes to installer. This updates the schema signature to the correct hash
so the upgrader can continue.
This addresses an issue where we've never added the `version` column to any
of the upgrade patches so if someone were to upgrade from pre-1.8, they will
not have the `version` column and they will not be able to install plugins.
This adds a prepared statement to check if the column already exists, if it
does not exists we will add the column. We have to use a prepared statement
as unfortunately MySQL doesn’t have the concept of `ADD COLUMN IF NOT
EXISTS` like MariaDB does.
This addresses an issue where the Task Title field allows any Admin to
remove the View and Required perms for Agents even though this field should
be Viewable and Required. This adds SQL so we can see if the
`FLAG_AGENT_REQUIRED`, `FLAG_AGENT_VIEW`, `FLAG_MASK_REQUIRE` and
`FLAG_MASK_VIEW` flags already exists, if not, we will add them to ensure
the field is Viewable and Required for Agents and to ensure Admins cannot
change this behavior for both perms. This also addresses an issue where the
Task Description field allows any Admin to remove the View perms for Agents
even though this field should always be Viewable. This adds SQL so we can
see if the `FLAG_AGENT_VIEW` and `FLAG_MASK_VIEW` flags already exists, if
not, we will add them to ensure the field is Viewable to Agents and to
ensure Admins cannot change this behavior.
This commit fixes an issue we had with Auto Referrals. If a Ticket had been transfered/responded to by 3 or more departments and a user sent in an email response to one of the transferred departments (not including the original or current department), we created an auto referral for that department which could potentially give agents to access they should not have access to.
A new column, email_id, has been added to the thread_entry_email table so that we can see which system email each thread entry has been fetched from.
This commit also adds the event (EVENT_TABLE) relationship to the ThreadEvents (THREAD_EVENT_TABLE) class.
An index for ticket_pid on the ticket table has been added.
This commit fixes an issue with the getChoices method for the new SLAChoiceField class. It needed the $options variable to be added so that it would match the parent class.
- Use get2FAConfig to check if 2FA backend is verified. This eliminates the is2FAConfigured function
- Check to make sure staff and staff is admin before allowing an agent to reset another agent's 2FA
- Only reset the default2fa when resetting 2FA (leave the configuration)
- Make sure there is an id before trying to call enable2fa
- Change login 'Loading' wheel to 'Verifying'
- Make sure 2FA backend is saved AND configured
- Give Admins option to reset 2FA for an Agent if they lose ability to log in w/current 2FA config
- The getConfigsByNamespace function is useful for 2FA so that we can use the value of an Agent's default_2fa to check to see if they have their 2FA configured
- Add Help Tip for require_agent_2fa field
- Do not automatically select 2FA option if it's configured, just enable it.
- Add Login loading wheel
This commit adds an email template for sending out the 2FA token.
**Note:** We will need to add an upgrader task to import the template for existing helpdesks. I'll add it below in the comments.
This commit adds to the functionality of two factor authentication for osTicket.
- Ensures that we do not clear out external 2fa configurations
- Enables 2fa options in the dropdown box of the profile when they are configured
- Adds help tip to the Default 2FA field
- Forces Agents to configure and save 2FA if 'Require agents to turn on 2FA' is checked upon next login
- Fixes the following error:
- Call to a member function getTabs() on null in include/staff/templates/navigation.tmpl.php
This commit improves upon how osTicket enforces password policies
systemwide for Agents and Users. Notable changes include;
* Ability to enforce policies on login
* Ability to specify applicable policy for Agents or Users alike
* Allow Password Policy plugins to expire passwords
This addresses issue 4909 where setting a translated Form Instruction fails
to render properly on the client side. This is due to us formatting the
instructions but not decoding before we render. This adds the decode method
to the translated Form Instructions so they are rendered properly on the
client side.
This addresses an issue where people are getting the incorrect time on
tickets even though they have all the timezones set correctly. The
current MySQL variable the system uses to determine the timezone is
`system_time_zone`. This variable is set by the server and sometimes
cannot be updated properly (or cannot be updated at all). This changes
the variable from `system_time_zone` to `time_zone` so if in the event
the system returns the incorrect time and they can’t update the server
timezone properly, they can just change the `@@global.time_zone` and
`@@session.time_zone` MySQL variables and should get the correct time.
2018-07-17 10:16:34 -05:00
1324 changed files with 145861 additions and 43168 deletions
Some files were not shown because too many files have changed in this diff
Show More
Reference in New Issue
Block a user
Blocking a user prevents them from interacting with repositories, such as opening or commenting on pull requests or issues. Learn more about blocking a user.