BoldSign®Effortlessly integrate e-signatures into your app with the BoldSign® API. Create a sandbox account!
<ejs-richtexteditor id="defaultRTE" [insertImageSettings]="insertImageSettings" (imageUploading)="onImageSelected($event)">
</ejs-richtexteditor> |
public onImageSelected(args: any): void {
// Setting Authorization Header
args.currentRequest.setRequestHeader(
"Authorization",
"Bearer ${token key to be passed}"
);
// You can also add additional parameters as key-value pair
args.customFormData = [{ name: "Syncfusion INC" }];
} |
public onComplete(args) {
if (args.requestType === 'Image'){
this.imageElement = args.elements[0];
this.imageElement.src = this.imageElement.src + '?access_token=mF_9.B5f-4.1JqM';
}
} |
public getImage() {
var request = new XMLHttpRequest();
this.imageElement.src = this.imageElement.src + '?access_token=mF_9.B5f-4.1JqM';
request.open('GET', this.imageElement.src, true);
request.setRequestHeader('Authorization', 'Bearer ' + 'test_123');
…
request.send();
}
|
Hi Indrajith,
I have a problem slightly different from what was discussed above.
I have an api to upload files which takes two parameters:
public onImageUploadSuccess = (args: any) => {
if (args.e.currentTarget.getResponseHeader('name') != null) {
// File name returned from the server, if added in the header
args.file.name = args.e.currentTarget.getResponseHeader('name');
}
}
Server
// Adding the modified headers in the response
Response.Headers.Add("name", imageFile);
|
We have the same issue.
For the moment we will implement random guid like resource id as part of url.
Considering it is behind TLS, that part of url is encoded and we'll have to put up with it for the moment.
Yet, we would also very much prefer to implement proper security via header with jwt.
Considering there are already examples of custom upload,
( Upload image directly to AWS S3 using pre-signed URL | Angular - EJ 2 Forums | Syncfusion)
and that there is event to sanitize html, Syncfusion please consider either one:
Thanks,
Hi Muamer,
We have validated your reported query "publishing sanitization event of GET request from rte component or utilizing existing authorization interception in Angular". You can achieve your requirement by using the ‘imageUploading’ event in the Rich Text Editor. In that event, authorization headers can be set. We have also prepared a sample for your reference.
Code Snippet:
<ejs-richtexteditor id="defaultRTE" [insertImageSettings]="insertImageSettings" (imageUploading)="onImageSelected($event)"> </ejs-richtexteditor> |
public onImageSelected(args: any): void { // Setting Authorization Header args.currentRequest.setRequestHeader( "Authorization", "Bearer ${token key to be passed}" ); // You can also add additional parameters as key-value pair args.customFormData = [{ name: "Syncfusion INC" }]; } |
Can you please check the above sample, and let us know if it meets your requirements?
Hello Vinothkumar Yuvaraj,
Thanks for your response.
We are already using this for upload. The issue is not with the upload but reading i.e. downloading that image later on when rich text editor is rendering its content.
Consider the following minimalistic sample:
Source code of sample is:
<p>Sample text</p>
<p>
<img style="opacity: 1; max-width: 1343px;" src="http://orka.lan/v2/resources/download/3a2e3c54-edd7-480e-86b1-4acf906c2fe4" alt="3a2e3c54-edd7-480e-86b1-4acf906c2fe4" class="e-imgbreak e-rte-image">
</p>
So, image tag of provided sample contains a link to actual image resource. If given resource is protected with jwt, there is no way we can affect implicit load that rich text editor is doing.
If protected, image would be unavailable.
Hi Muamer,
We hope the following solution meets your requirements.
We have made a sample to meet your requirements. In this sample, we have removed the image element src based on the authorization token. Please take a look at the following code and sample.
<ejs-richtexteditor [insertImageSettings]="insertImageSettings" (imageUploading)="onImageSelected($event)" (actionComplete)='complete($event)' (imageUploadSuccess)='imageUploadSuccess($event)' > </ejs-richtexteditor> |
export class AppComponent { public accessTokan = []; public tokenName = 1; public imageToken = false; private insertImageSettings: Object = { saveUrl: http://localhost:62869/api/richtexteditor/SaveFile, path: http://localhost:62869/Images/ };
public onImageSelected(args: any): void { // Setting Authorization Header args.currentRequest.setRequestHeader( "Authorization", "Bearer ${token}" + this.tokenName ); this.accessTokan.push("Bearer ${token}" + this.tokenName) this.tokenName++; } public complete(args): void { if (args.elements[0] != null && this.imageToken) { if(args.elements[0].tagName == 'IMG'){ args.elements[0].src = ""; this.imageToken = false; } } } public imageUploadSuccess = (args: any) => { if (args.e.currentTarget.getResponseHeader("url") != null) { var token = args.e.currentTarget.getResponseHeader("url"); if(this.accessTokan.indexOf(token) > -1){ this.imageToken = true; } } } } |
Server
public ActionResult SaveFile(IList<IFormFile> UploadFiles) { try { HttpContext.Request.Headers.TryGetValue("Authorization", out StringValues HeaderContent);
foreach (IFormFile file in UploadFiles) { if (UploadFiles != null) { // string filename = ContentDispositionHeaderValue.Parse(file.ContentDisposition).FileName.Trim('"'); filename = _hostingEnvironment.WebRootPath + \\Images + $@"\{filename}"; if (!System.IO.File.Exists(filename)) { using (FileStream fs = System.IO.File.Create(filename)) { file.CopyTo(fs); fs.Flush(); }
} // Modified image URL to the response headers Response.StatusCode = 200; Response.Headers.Add("url", HeaderContent.ToString());
Response.ContentType = "application/json; charset=utf-8"; } } } catch (Exception e) { Response.Clear(); Response.ContentType = "application/json; charset=utf-8"; Response.StatusCode = 204; Response.HttpContext.Features.Get<IHttpResponseFeature>().ReasonPhrase = "No Content"; Response.HttpContext.Features.Get<IHttpResponseFeature>().ReasonPhrase = e.Message; } return Content(""); } |
If it does not meet your requirement, can you please share more details about your requirement? This will help us provide a better solution from our end.
Hi Muamer,
Additionally, we would like to inform you that by loading the initial image on the server side, we can protect the image on the server. However, we can't show the image from the server.
It seems like this issue is still not fixed or correctly adressed because I think the use case was not properly understood.
An use case is: I write an article with your rte editor and I only want this article to be available to 2 out of 10 employees. Then I upload images in that article (which hold highly sensitive information). The article with the RTE cannot be accessed by my employees, but someone sent around the URL with the image that has to be public for the RTE as it must have a URL to an image that is public without authorization and everybody can now see this image. Hence, we need to ensure that the URL with the image can only be accessed through authorization. Then the RTE doesn't display it properly anymore.
How can we add images to an RTE and tell the RTE that it needs to check the JWT token before displaying the image because someone unauthorized might be staring at the RTE.
Thanks
public actionComplete (args): void { if (args.elements[0] != null && !this.imageToken) { if(args.elements[0].tagName == 'IMG'){ // here you can remove the src of the image, if they don't have the image token args.elements[0].src = ""; this.imageToken = false; } } } |
Since nobody talked about a workaround yet, I will add one here for everyone who is struggling with this like me. I hope that syncfusion will provide a proper solution for this though as it should be part of a RTE in my opinion.
After the RTE is created, my workaround loops over all <img> elements, then loading the images with a JWT token from the backend and lastly replaces the image with a generated blob in a URL that is stored on localhost in the browser. I also ensured to cleanup the rendered URLs as it could lead to potential memory issues:
Here is the RTE editor in HTML with the created event:
Here is the function to replace the images in Angular (Typescript). The URL to load the image in my case is http://<backendUrl>/api/download/:id, hence I split() and pop().
You might have noticed that I stored the blob url and the backend url both in the blobURLs
I did this because of two reasons. First, when destroying the component the urls should be cleaned up to avoid any memory issues:
Second, I also need to change the url back when saving the document to the database:
Then here is the code for adding an image:
Hope this solution helps others.
Hey Vinitha,
just saw your response. Thanks for that, but that still doesn't help. What your solution fixes is that the image is not in the RTE anymore if you don't have a token. However, the image still has to be publicly available in the internet to be showed in the RTE in case you have a token. And for many users of the RTE that is a no go. Hence, my solution hopefully helps a couple people in the future until you guys might fix this. Let me know if you'll consider that or if you have any questions.