How to handle image tag in Rich Text field in Sitecore, so that it can handle the media hash automatically? - caching

My Sitecore website is on 7.5. I have implemented a media protection request feature, but I can see too many errors in Sitecore logs saying that:
ERROR MediaRequestProtection: An invalid/missing hash value was
encountered. The expected hash value: Media URL: , Referring URL:
My question is How to handle an image tag in Rich Text field in Sitecore, so that it can handle the media hash automatically?

Since version 7.5 Sitecore introduced a Media Request Protection which is a hash added to assets' URLs. I think that this was a good thing to avoid any kind of denial of service attacks.
On every incoming media request Sitecore calculates the hash of the request query string parameters and compares it with the given hash. If they are equal then Sitecore will perform the needed routine based on the provided URL parameters (for example, image resizing), but if they are not equal then Sitecore will throw a MediaRequestProtection error and send the original file as is.
There is a known issue in Sitecore Rich Text Editor (RTE) with 438674 Ticket Id and "Media request protection is not applied to media in a hyperlink within the RTE" description. Sitecore Support can provide a patch to override the method for rendering media links from RTE fields to also include the hash value. See the reference under Sitecore 8.2 release notes here.
If you don't have any Sitecore Support coverage by now then you can implement a workaround as follows:
Hook into saveRichTextContent pipeline to alter the RTE content before saving. For items that haven’t been modified after the saveRichTextContent pipeline has been introduced you can create a new renderField pipeline for Rich Text field type, but I would rather recommend to stick to saveRichTextContent pipeline approach and simply re-save all items with RTEs containing media assets.
Write your custom code to loop through images within the RTE HTML and modify the image rendering accordingly. Note, that you need to use Sitecore.Resources.Media.HashingUtils.ProtectAssetUrl() method to generate the full URL with the hash added, for example:
string mediaUrl = Sitecore.Resources.Media.MediaManager.GetMediaUrl(yourMediaItem);
string safeMediaUrl = Sitecore.Resources.Media.HashingUtils.ProtectAssetUrl(mediaUrl);

Related

Attach meta data / custom data to slack messages sent through the API

I am developing a series of Slack apps for my workspace, and some of them are meant to interact with the content (messages) delivered by the other apps : extracting content IDs that may be referred to by other messages
A concrete example :
Suppose I have an app A "FindUser" that is capable of giving me the user profile when a slack user types find me#example.com, and it replies in the thread with a formatted view of the user profile
I am developing an app B "EditTags", which basically gives me a right click option with "edit tags" (see Slack's Interactive Components/Actions), the idea being that a user could first ask app A to find a user, and then right click on the reply from App A and click the "edit tags" action given by the other app. What this app B does it actually retrieve the tags for the user mentionned by the previous message from app A, and in another reply to the thread it gives some controls to either delete an existing tag OR it shows a select with autocomplete to add new tags.
The B app needs to retrieve the user ID that the A app mentionned previously. So I need some way to pass that data directly in the slack message. When looking at the examples, slack does not seem to provide a way to add arbitrary "metadata" to a message, am I wrong ? Do you have workaround for this ? I mean I could totally send the user ID say, in the footer, so I can just read the footer, but I was planning to use the footer for something else... Is there a way to pass metadata hrough properties that would be hidden to the end user ?
Although this does not feel relevant, I am building a slack nodeJS app using the node slack sdk (and especially the #slack/interactive-messages package)
For the most part the Slack API does not provide any official means to attach custom data / meta data to messages. But with some simple "hacks" it is still possible. Here is how:
Approach
The basic approach is to use an existing field of the message as container for your data. Obviously you want to pick a field that is not directly linked to Slack functionality.
Some field are not always needed, so you can just use that field as data container. Or if its needed, you can include the functional value of that field along with your custom data in the data container.
For example for message buttons you could use the value field of a button and structure your code in a way that you do not need it in its original function. Usually its sufficient to know which button the user client (via the name field), so the value field is free to be used for your custom data. Or you can include the functional value of your button along with the custom data in a data container (e.g. a JSON string) in that field.
Serialization
All messages are transported through HTTP and mostly encoded as UTF-8 in JSON. So you want to serialize / de-serialize your data accordingly, especially if its binary data. If possible I would recommend to use JSON.
Length
The maximum allowed length of most fields is documented in the official Slack API documentation. e.g. for the value field for message buttons can contain up to 2.000 characters. Keep in mind that you need to consider the length of your data after serialization. e.g. if you convert binary data into Base64 so it can be transported with HTTP you will end up with about 1.33 characters for every byte.
Contents
In general I would recommend to keep your data container as small as possible and not include the actual data, but only IDs. Here are two common approaches:
Include IDs of your data objects and load the actual objects
from a data store when the request is later processed.
Include the ID of server session and when processing the request you
can restore the corresponding server session which contains all data
objects.
In addition you might need to include functional values so that the functionality of the field you are using still works (e.g. value of a menu option, see below)
Implementation
Dialogs
Dialogs provide an official field for custom data called state. Up to 3.000 characters.
Message buttons
For Message buttons you can use the message action fields / value. Up to 2.000 characters. Its also possible to use the name field, but I would advise against it, because the maximum allowed length of that field is not documented.
Message menus
For Message menus you can use the value field of an option or the name field of the menu action.
Usually the value field is the better approach, since you have a documented max length of 2.000 and it gives you more flexibility. However, you will need to combine you custom data with the actual functional value for each option. Also, this will not work for dynamic select elements (like users), where you can not control the value field.
When using the name field note, keep in mind that the maximum allowed length of name is not documented, so you want to keep you data as short as possible. Also, if you want to use more than one menu per attachment you need to include the actual name of the menu into your data container.
Normal message attachments
Normal message attachments do not contain any suitable field to be used as container for custom data, since all fields are linked to Slack functionality.
Technically you could use the fallback field, but only if you are 100% sure that your app is never used on a client that can not display attachments. Otherwise your data will be displayed to the user.

Set Input Parameter in Custom Workflow Activity, Dynamic values are not populating?

On the saving of Case record I want to assign the case to respective Agent based on case type , sub type and Client/Account,
I have a Assignee field on Account form which I need to get the Agent's name to Assign the case.
I am creating a custom workflow activity for that, but while writing it I stuck how to fetch Case forms record on which I apply logic.
Please suggest what is the good approach, do I need to make a retrieve call to fetch these parameters or something else.
While setting the Custom Step Input Properties drop down fields are not populating to select the Dynamics Values.
Better to use plugin, as the documented/supported preimage is available in plugin steps + flexible.
You have to look for type, subtype, etc in target entity (incident in your case) or preimage if needed to apply logic.
If you still want to use workflow, go ahead & follow this article.
we can always read Pre image and Post image in the plug-in for various purpose. However, in workflow, we may sometimes want to read Pre Image for some purpose. Now we can also read Pre Images and Post Images in the workflow using Execution Context. It uses the same Plug-in Architecture and hence we can use it to read Pre Images and Post Images. However, this concept is not documented in the SDK so it might be unsupported.

Adding custom data based attributes based on Response object

Halo ! I'm trying to implement dropzonejs in a very specific way. Actually I follow the standard implementation described on the official page. Everything works perfectly.
But I'm willing to attach the server's generated URI for each uploaded file directly when uploaded : when uploading it's creating a database entry with some stuff like a page uri with title etc. This mean that the server would return as a response the id of the database saved file in order to attach the href attribute with its value to the the element in front.
This is quite ok to do this when only one file is uploaded, but it becomes trickier when bulk uploading.
So maybe I didn't understand the documentation well (and I'm quite sure I didn't), but is there any way to add custom data-dz-like attributes based on my server's response ? I'd like something like data-dz-url where the url points to a database entity (not the file itself).
Or if not if there is an "easy way" to handle this.
Thanks a lot
Here is the answer :
myDropzone.on('success', (file, response) => {
file.previewElement.href = "/admin/media/"+response.id+"/show/"
})
file is reference to the current uploaded element. It's possible to extend it's html attributes through previewElement. Setting the data-type attribute in the template before, then assigning it the right value works aswell.
Hope this will help some.

jqgrid autoencode=true encode postdata

I'm trying to fix XSS vulnerabilities across my web application and I'm stuck with jqGrid.
I activated 'autoencode' for all my grids and the documentation says : "When set to true encodes (html encode) the incoming (from server) and posted data (from editing modules).".
My problem is that I don't understand why posted data are encoded. This way I'm getting html escaped text in my database. So this database is no more readable by an other application (or it has to decode all texts), and in addition database search doesn't work any more.
So, is it possible to only encode data retrieved from database and post data as it ?
Currently, I disabled autoencode and added formatter on all my columns to escape all text. Is it the only way ?
You can use serializeEditData (in case of usage form editing), serializeRowData (in case of usage inline editing) or serializeCellData (in case of usage cell editing) to change the data which will be send to the server during editing. To decode the data you can use for example $.jgrid.htmlDecode. You can enumerate all properties of posted data and decode the value of the corresponding property. Alternatively you can use decoding of posted data on the server side. Any technology which you use on the server provide simple method which can be used for decoding. For example in ASP.NET one can use HtmlDecode/HtmlEncode methods of HttpServerUtility.

Ajax results filtering and URL parameters

I am building a results filtering page using AJAX requests. I would like to reflect the filters in the URL. For example: for price_from I want to add ?price_from=VAL to the URL.
I have a backend that is capable of rendering the page with URL parameters.
After some googling I would a Backbone.router solution which has a hash fallback for the IE that does not support HTML5 history API.
I have a problem with setting a good philosophy of routes. I have a set of filtering parameters (price_from, price_to, color, ...) and I would like to attach each parameter to one route.
Is that possible to chain the routes to match for example: ?price_from=0&price_to=1&color=red? (the item order can change)
It means: call all the routes at the same time and keep the ie backwards compatibility?
Your best bet would be to have a query portion of the URL rather than using GET parameters to denote the search criteria. For example:
Push state: /search/query/price_from=0&price_to=1&color=red
Hash based: #search/query/price_from=0&price_to=1&color=red
Your backend would of course need to change a bit to be able to parse the new URL structure.

Resources