Showing posts with label ImagePaste. Show all posts
Showing posts with label ImagePaste. Show all posts

2013/11/17

Finally, SimpleUploads 4 is here

After a long time working on this upgrade, I've reached the point where I think that it's better to release it and write all the documentation that I had in mind afterwards, so expect more updates about all the features in the following days.

Since quite a long time ago I felt that the name "ImagePaste" wasn't correct for a plugin that allows to also drop files and since version 3.0 offered two buttons to upload files or images with just two clicks and get them inserted into CKEditor.

So with along a new feature set, the main change (meaning the change that will cause more problems for existing users because instead of just replacing the files now you have to edit again your config file) is the rename of the old "imagepaste" to "simpleuploads"

That name tries to explain better what it does, it's not only about "images" and not only about "paste", it's a set of features to offer the users a way to "upload" files in a "simple" way.

The best way to check how it works is to test the demo.

Skipping the explanation about the existing features, the new ones are focused on the dialogs of CKEditor and improving the upload progress:

When you upload a file in the editor, now you get a progress indicator and the option to cancel the upload. The existing progress for images has been improved to also include the cancel option.

The plugin now integrates into the CKEditor dialogs, if it finds a "quickUpload" button it will be replaced with its own one to offer the same simple upload (click button, select a file and you're done instead of having to press the "upload to server"), as well as progress information, cancelation option and the full control on the upload (modify the upload URL, check file size, extension, automatica validation with a whitelist or blacklist...)

And besides modifying the QuickUpload button, the dialog itself now becomes a drop target, you can drop a file from your computer on those dialogs (even if there's only a browse server button is enough) and it will be uploaded and the url of the dialog filled with the new URL.

Another improvement in this version is the inclusion of optional parameters in the upload data, for example if you want to use some anti-CSRF token, modifying the QuickUpload system in CKEditor required some tricks, but now it's a piece of cake. Ditto if you want to add for example a checkbox to scale the image to a maximum, just before the upload begins there's an event where you can control many features.

I'll try to provide examples about how to customize CKEditor with this plugin so you can easily upload files and do whatever you want with them, so keep an eye on the blog because I'll try to write new posts explaining different ways to use the plugin. I've created now a main page here to provide a central point for all the information about SimpleUploads.

PS: currently I really dislike the comment system in Blogger because I don't get any notification when someone comments a post, so I might move to another platform if this bug persists. Meanwhile, have a little patience if I don't reply, it's usually better to send me a mail or direct message by + me.

2013/10/06

Cross domain file uploads in CKEditor

In version 3.4 of the SimpleUploads plugin I've added support to upload files across domains based on the CORS spec.

If you don't use multiple domains (one server for the uploaded files and another for the editing page) then this change shouldn't affect you. Otherwise you can enable this feature by modifying your uploader to send just two headers in response to an OPTIONS request.
Some simple PHP code:
if (isset($_SERVER["HTTP_ORIGIN"])) {
 // You must verify that the origin domain is on your white-list
 header('Access-Control-Allow-Origin: https://admin.example.com');
 header('Access-Control-Allow-Credentials: true');
}
if ($_SERVER['REQUEST_METHOD']=='OPTIONS')
 exit(0);
  • First: check if the browser has sent an Origin header. That means that it's a cross domain request. You can check that domain with the list of domains that you want to allow. The usual behavior is to send back a fixed origin header like
    header('Access-Control-Allow-Origin: https://admin.example.com');
  • Second: Send an Access-Control-Allow-Credentials header specifying that the browser is allowed to make a request that will use the credentials of the user at this domain. This means that if the user is logged in, the browser will send the cookies required to allow you check his/her identity.
  • Last: as the OPTIONS request doesn't require more data in the response you can stop any further processing here. After this first request the browser will upload the file and you must send back again the two Access-Control headers as shown in the sample code.
You must be careful if you want to allow this feature, after all it opens the possibility of another attack vector.
If you're hosting the files in the same physical server, you might be able to get the same functionality by modifying just the URL that it's returned after you upload a file and keeping all your code in the admin.example.com domain.

2013/08/10

A basic upload script for CKEditor

A long time ago I published a basic example showing the skeleton of how an upload script for CKEditor should look like. Since the release of the imagepaste plugin I've received some requests to fill and explain all the details, and some people buy that plugin even before testing the free version and then they find that they don't know how to upload files.

So now I'm publishing that script with the missing part, a simple call to

move_uploaded_file($_FILES["upload"]["tmp_name"], $basePath . $name);

I've adjusted it a little so that the path to the upload folder and matching URL can be configured more easily, but it's still a very basic script. It doesn't perform any check on the uploaded files, you must take care of integrating it with your CMS (after all, that's something impossible for me to know how you're doing that part) and verify that the upload folder has the right permissions.

You can use it with CKEditor to enable the Upload tab in the Image and Link dialogs, and that way the user will be able to upload files (but not browse the existing ones). If you add the free version of the image paste plugin, then the user will be able to paste images from their clipboard into CKEditor, and the content will not be that huge mess of base64 encoded data, but a simple URL to your server with all the performance benefits that it means.

At this point, you can opt to buy the full version of the image paste plugin if you want to provide even more options for the users:

  • Drag and drop from the computer for every modern browser
  • Pasting images from the clipboard in Chrome (besides the basic pasting available in the free version for Firefox)
  • Copy and paste a file from your computer in Firefox
  • Two buttons to quickly upload a file or image for every browser. There's no way to make uploads simpler than this, other plugins still require the user to open a dialog, click browse, upload, etc... that's a huge mess and a big waste of time. Here you click and the file picker launches automatically, select the file that you want and then it's uploaded and inserted in a single step.

You can test all these features in the demo page for CKEditor 4 (the plugin also works with CKEditor 3)

Back to this upload script:

I've published it at GitHub so if other people wants to provide some suggestions for better compatibility or they take the time to improve it I will try to keep it updated, but I don't really want to spend too much time on it because if by a miracle it would be a success (in fact, I wouldn't like to see too many people using this because it's really basic) then attackers would love to exploit all the weakness that it has. Please, read the documentation, all the comments and try your best to secure it as much as you can. If you download it from GitHub, you can remove those extra .git* files that it has added automatically as well as the readme and the docs when you have read them.

You only need the upload.php file and to improve a little the security by obscurity you can opt to rename it anyway that you want, just put that same name and path in the configuration of your CKEditor.

The best option would be for you to take this script as a full example and then add your customizations, your own security options, make it unique so that a simple bot can't find and use it.

This is the link to download the current version from GitHub.

2013/08/02

Making the ImagePaste plugin compatible with IE11

Now that it's summer time and I have some free time I decided to take a look at the beta of IE 11 to check how well does it work with some of my CKEditor plugins.

The first thing to remember is that CKEditor itself isn't compatible with IE11 and if we are to base our guesses on previous history I don't think that they will really work on it until sometime after IE11 has been released and people start complaining seriously, but I prefer to look ahead and try to work now instead of having to rush later.

So I've focused my tests on the image paste plugin, specially because in their release notes they talk about the new ability to use the .files property in the clipboardData object as well as the base64 encoding performed by default (like Firefox).

Well, using base64 on the image is a nice little trick, but I think that it's really a bad option in the real world. I guess that if any performance guru would have been consulted they would have answered that this feature shouldn't have been added (at least not by default).

Testing IE nowadays it's much simpler than it used to be. Microsoft provides virtual machines ready to use with almost any combination of supported OS and IE as well as the virtual machine environment (at least I didn't miss anything). So after downloading the Win 8.1 preview and "installing" it, I was ready to test.

Ok, almost ready to test: no network connection. It turns out that the default network configuration is set up to work as a private network with the host. After changing it to my default bridged preference I had Internet again :-)

So I launched my demo with CKEditor 3 and... nothing. Nothing is pasted there. Not only the image is ignored from the clipboard, also any text can't be pasted. As the argument will be that CKEditor is "old" and it's not supported I moved then to the CKEditor 4 demo to check it, and yes, now it "works". The image is pasted but as base64 data. That means that neither my direct paste listener on the element is working to detect the files and the default CKEditor paste event is also failing to provide me the base64 so I could try to use the same Firefox trick.

A little debugging shows that the CKEditor paste isn't fired at all and my listener on the editable element works, but the event doesn't seem to include the .files property. Debugging that info isn't as easy as it seems, despite the claim that after pressing F12 the debugger is ready isn't true for me, breakpoints doesn't work, the files show up as a huge list of "plugin.js" files...

At this point a very important suggestion for Microsoft: Show folder names in the pane with the loaded scripts, having around 30 or 50 files named "plugin.js" and no way to tell them apart is not fun.

In order to debug correctly I restart the machine (maybe it's usual for people to start debuggin on the first IE & OS launch, but I don't see any other reason to fire up that VM, Win8.1 still tries to force "metro" too much so it doesn't fit my tastes) and now things seem to work a little better. To find the place for my breakpoints I search the files for the some function name specific to that file and that way I can avoid the mess of "plugin.js" .

And now looking at their documentation I notice something interesting, instead of using a clipboardData object on the paste event data, they are using one one the window object (like old IEs), so now it's obvious why this detection wasn't working. I add a workaround to try to use it and now when I copy an image from Paint I can detect and upload it like it happens in Firefox and Chrome. Due to the way that they have written their documentation I think that this feature isn't complete, after all I haven't managed to get an event if I try to paste a file from the desktop (like Firefox does) and if I create a document in WordPad with an image only the text is copied and no image is inserted, although given the way that they have chosen to write the documentation I think that some other feature should be available in the final version besides pasting a simple image from the clipboard.

After noticing that issue and given that this is a problem that shouldn't exist (providing files in the clipboard data is a feature that currently only Firefox and Chrome support, so if Microsoft want existing code to work they should use exactly the same APIs and objects) I filed a bug in their tracker to check if they care about compatibility or not. To my surprise this morning I had a reply, stating that obviously they can't reproduce the bug and the best course of action is to close it. I've replied providing the test file as a live url instead of an attachment (they didn't allow .html attachments so finding a .txt page might have been too hard for them). Of course this probably means the end of my efforts to report any issue in IE11 to Microsoft, if they don't care about something so simple and basic according to their goal of treating IE11 as any other modern browser then I'm not gonna waste my time trying to explain more complex things.

Back to my testings on IE11 and image paste, I noticed that dropping a file doesn't upload it and instead tries to open it as if I hadn't added any drop listeners. In this case the problem is that CKEditor at the moment detects IE11 as a gecko, but in this case Microsoft is aligning their behavior to old Chrome and requires that the drag over event is prevented. This is the kind of bug that Microsoft should also fix, but I don't have hope on them so I just add a line to detect "IEmodern" and it works (yes, this is the kind of bug/browser behavior that can't be changed based on feature detection but instead it relies on hardcoding which are the buggy browsers)

So now I tested again the CKEditor 3 demo and everything related to my plugin works. Images can be pasted, dragged, uploaded with the toolbar button... CKEditor itself has its own set of bugs (like not being able to paste at all in 3.6 or that the paste event isn't fired in 4.2) but that's outside my control. I could try to debug and provide patches if I really cared, but given that some of the patches that I provided for CKEditor have been ignored for years I prefer to not waste the time that way.

BTW, soon I might replace all the CKEditor 4 demos with the "Moono color" skin, being forced to see those black and white icons is really depressing.