Sfoglia il codice sorgente

Support for changing headers. Added some docs.

Kamil Piechaczek 6 anni fa
parent
commit
6a4510eec3

+ 46 - 0
packages/ckeditor5-upload/docs/features/simple-upload-adapter.md

@@ -0,0 +1,46 @@
+---
+category: features-image-upload
+menu-title: Simple Upload Adapter
+order: 50
+---
+
+# Simple Upload Adapter
+
+The {@link module:upload/simpleuploadadapter~SimpleUploadAdapter} plugin that enables file uploads in CKEditor 5 using the external side-server connection.
+
+## Installation
+
+To add this feature to your editor install the [`@ckeditor/ckeditor5-upload`](https://www.npmjs.com/package/@ckeditor/ckeditor5-upload) package:
+
+ ```bash
+npm install --save @ckeditor/ckeditor5-upload
+```
+
+And add it to your plugin list:
+
+ ```js
+import SimpleUploadAdapter from '@ckeditor/ckeditor5-upload/src/simpleuploadadapter';
+
+ClassicEditor
+	.create( document.querySelector( '#editor' ), {
+		plugins: [ SimpleUploadAdapter, ... ],
+		toolbar: [ ... ],
+		simpleUpload: {
+			...
+		}
+	} )
+	.then( ... )
+	.catch( ... );
+```
+
+<info-box info>
+	Read more about {@link builds/guides/integration/installing-plugins installing plugins}.
+</info-box>
+
+## Configuration
+
+All available options are defined in the {@link module:upload/simpleuploadadapter~SimpleUploadConfig} interface. 
+
+ ## Contribute
+
+ The source code of the feature is available on GitHub in https://github.com/ckeditor/ckeditor5-upload.

+ 68 - 11
packages/ckeditor5-upload/src/simpleuploadadapter.js

@@ -14,6 +14,8 @@ import FileRepository from './filerepository';
 import log from '@ckeditor/ckeditor5-utils/src/log';
 
 /**
+ * A plugin that enables file uploads in CKEditor 5 using the external side-server connection.
+ *
  * @extends module:core/plugin~Plugin
  */
 export default class SimpleUploadAdapter extends Plugin {
@@ -70,7 +72,7 @@ class Adapter {
 	 * Creates a new adapter instance.
 	 *
 	 * @param {module:upload/filerepository~FileLoader} loader
-	 * @param {Object} options
+	 * @param {module:upload/simpleuploadadapter~SimpleUploadConfig} options
 	 * @param {String} options.uploadUrl A URL where the image will be sent.
 	 */
 	constructor( loader, options ) {
@@ -82,9 +84,9 @@ class Adapter {
 		this.loader = loader;
 
 		/**
-		 * Test.
+		 * The configuration of the adapter.
 		 *
-		 * @member {Object} #options
+		 * @member {module:upload/simpleuploadadapter~SimpleUploadConfig} #options
 		 */
 		this.options = options;
 	}
@@ -146,7 +148,7 @@ class Adapter {
 		xhr.addEventListener( 'load', () => {
 			const response = xhr.response;
 
-			// This example assumes the XHR server's "response" object will come with
+			// We assume the XHR server's "response" object will come with
 			// an "error" which has its own "message" that can be passed to reject()
 			// in the upload promise.
 			//
@@ -158,8 +160,7 @@ class Adapter {
 
 			// If the upload is successful, resolve the upload promise with an object containing
 			// at least the "default" URL, pointing to the image on the server.
-			// This URL will be used to display the image in the content. Learn more in the
-			// UploadAdapter#upload documentation.
+			// This URL will be used to display the image in the content.
 			resolve( {
 				default: response.url
 			} );
@@ -184,17 +185,73 @@ class Adapter {
 	 * @param {File} file File instance to be uploaded.
 	 */
 	_sendRequest( file ) {
+		// Set headers if specified.
+		const headers = this.options.headers || {};
+
+		for ( const headerName of Object.keys( headers ) ) {
+			this.xhr.setRequestHeader( headerName, headers[ headerName ] );
+		}
+
 		// Prepare the form data.
 		const data = new FormData();
 
 		data.append( 'upload', file );
 
-		// Important note: This is the right place to implement security mechanisms
-		// like authentication and CSRF protection. For instance, you can use
-		// XMLHttpRequest.setRequestHeader() to set the request headers containing
-		// the CSRF token generated earlier by your application.
-
 		// Send the request.
 		this.xhr.send( data );
 	}
 }
+
+/**
+ * The configuration of the {@link module:upload/simpleuploadadapter~SimpleUploadAdapter simple upload adapter}.
+ *
+ *		ClassicEditor
+ *			.create( editorElement, {
+ *				simpleUpload: {
+ *					uploadUrl: '',
+ *					headers: {
+ *					    ...
+ *					}
+ *				}
+ *			} );
+ *			.then( ... )
+ *			.catch( ... );
+ *
+ * See {@link module:core/editor/editorconfig~EditorConfig all editor configuration options}.
+ *
+ * @interface SimpleUploadConfig
+ */
+
+/**
+ * The configuration of the {@link module:upload/simpleuploadadapter~SimpleUploadAdapter simple upload adapter}.
+ *
+ * Read more in {@link module:upload/simpleuploadadapter~SimpleUploadConfig}.
+ *
+ * @member {module:upload/simpleuploadadapter~SimpleUploadConfig} module:core/editor/editorconfig~EditorConfig#simpleUpload
+ */
+
+/**
+ * The path (URL) to the server which handles the file upload. When specified, enables the automatic
+ * upload of resources such as images inserted into the content.
+ *
+ * @member {String} module:upload/simpleuploadadapter~SimpleUploadConfig#uploadUrl
+ */
+
+/**
+ * An object that defines additional headers for request that is being sent during the upload. This is the right place to
+ * implement security mechanisms like authentication and CSRF protection.
+ *
+ *		ClassicEditor
+ *			.create( editorElement, {
+ *				simpleUpload: {
+ *					headers: {
+ *					    'X-CSRF-TOKEN': 'CSFR-Token',
+ *					    Authorization: 'Bearer <JSON Web Token>'
+ *					}
+ *				}
+ *			} );
+ *			.then( ... )
+ *			.catch( ... );
+ *
+ * @member {Object.<String, String>} module:upload/simpleuploadadapter~SimpleUploadConfig#headers
+ */

+ 42 - 0
packages/ckeditor5-upload/tests/simpleuploadadapter.js

@@ -150,6 +150,48 @@ describe( 'SimpleUploadAdapter', () => {
 				} );
 			} );
 
+			it( 'should modify headers of uploading request if specified', () => {
+				const editorElement = document.createElement( 'div' );
+				document.body.appendChild( editorElement );
+
+				return ClassicTestEditor
+					.create( editorElement, {
+						plugins: [ SimpleUploadAdapter ],
+						simpleUpload: {
+							uploadUrl: 'http://example.com',
+							headers: {
+								'X-CSRF-TOKEN': 'foo',
+								Authorization: 'Bearer <token>'
+							}
+						}
+					} )
+					.then( editor => {
+						const adapter = editor.plugins.get( FileRepository ).createUploadAdapter( loader );
+						const validResponse = {
+							uploaded: 1
+						};
+
+						adapter.upload();
+
+						return loader.file
+							.then( () => {
+								const request = sinonXHR.requests[ 0 ];
+								request.respond( 200, { 'Content-Type': 'application/json' }, JSON.stringify( validResponse ) );
+
+								const requestHeaders = request.requestHeaders;
+
+								expect( requestHeaders ).to.be.a( 'object' );
+								expect( requestHeaders ).to.have.property( 'X-CSRF-TOKEN', 'foo' );
+								expect( requestHeaders ).to.have.property( 'Authorization', 'Bearer <token>' );
+
+								expect( request.url ).to.equal( 'http://example.com' );
+
+								editorElement.remove();
+							} )
+							.then( () => editor.destroy() );
+					} );
+			} );
+
 			it( 'should throw an error on generic request error', () => {
 				const promise = adapter.upload()
 					.then( () => {