From f3dca2e82a73cf1414dbf9b564471c3a10a48abd Mon Sep 17 00:00:00 2001 From: ZsgsDesign Date: Mon, 24 Jan 2022 12:05:00 +0800 Subject: [PATCH] add robust CSRF support and provide default values for CSRF fields --- README.md | 4 +++- src/js/easymde.js | 15 ++++++++++++--- types/easymde.d.ts | 2 ++ 3 files changed, 17 insertions(+), 4 deletions(-) diff --git a/README.md b/README.md index f47da4c..98ff7ae 100644 --- a/README.md +++ b/README.md @@ -178,7 +178,9 @@ easyMDE.value('New input for **EasyMDE**'); - otherwise: `{"error": ""}`, where *errorCode* can be `noFileGiven` (HTTP 400), `typeNotAllowed` (HTTP 415), `fileTooLarge` (HTTP 413) or `importError` (see *errorMessages* below). If *errorCode* is not one of the *errorMessages*, it is alerted unchanged to the user. This allows for server side error messages. No default value. - **imagePathAbsolute**: If set to `true`, will treat `imageUrl` from `imageUploadFunction` and *filePath* returned from `imageUploadEndpoint` as an absolute rather than relative path, i.e. not prepend `window.location.origin` to it. -- **imageCSRFToken**: CSRF token to include with AJAX call to upload image. For instance used with Django backend. +- **imageCSRFToken**: CSRF token to include with AJAX call to upload image. +- **imageCSRFName**: CSRF token filed name to include with AJAX call to upload image, applied when `imageCSRFToken` has value, defaults to `csrfmiddlewaretoken`. +- **imageCSRFHeader**: If set to `true`, passing CSRF token via header. Defaults to `false`, which pass CSRF through request body. - **imageTexts**: Texts displayed to the user (mainly on the status bar) for the import image feature, where `#image_name#`, `#image_size#` and `#image_max_size#` will replaced by their respective values, that can be used for customization or internationalization: - **sbInit**: Status message displayed initially if `uploadImage` is set to `true`. Defaults to `Attach files by drag and dropping or pasting from clipboard.`. - **sbOnDragEnter**: Status message displayed when the user drags a file to the text area. Defaults to `Drop image to upload it.`. diff --git a/src/js/easymde.js b/src/js/easymde.js index dbb0135..d929420 100644 --- a/src/js/easymde.js +++ b/src/js/easymde.js @@ -1819,6 +1819,9 @@ function EasyMDE(options) { options.imageAccept = options.imageAccept || 'image/png, image/jpeg'; options.imageTexts = extend({}, imageTexts, options.imageTexts || {}); options.errorMessages = extend({}, errorMessages, options.errorMessages || {}); + options.imagePathAbsolute = options.imagePathAbsolute || false; + options.imageCSRFName = options.imageCSRFHeader || 'csrfmiddlewaretoken'; + options.imageCSRFHeader = options.imageCSRFHeader || false; // Change unique_id to uniqueId for backwards compatibility @@ -2390,10 +2393,11 @@ EasyMDE.prototype.uploadImage = function (file, onSuccess, onError) { var formData = new FormData(); formData.append('image', file); - // insert CSRF token if provided in config. - if (self.options.imageCSRFToken) { - formData.append('csrfmiddlewaretoken', self.options.imageCSRFToken); + // insert CSRF body token if provided in config. + if (self.options.imageCSRFToken && !self.options.imageCSRFHeader) { + formData.append(self.options.imageCSRFName, self.options.imageCSRFToken); } + var request = new XMLHttpRequest(); request.upload.onprogress = function (event) { if (event.lengthComputable) { @@ -2403,6 +2407,11 @@ EasyMDE.prototype.uploadImage = function (file, onSuccess, onError) { }; request.open('POST', this.options.imageUploadEndpoint); + // insert CSRF body token if provided in config. + if (self.options.imageCSRFToken && self.options.imageCSRFHeader) { + request.setRequestHeader(self.options.imageCSRFName, self.options.imageCSRFToken); + } + request.onload = function () { try { var response = JSON.parse(this.responseText); diff --git a/types/easymde.d.ts b/types/easymde.d.ts index 2aa161b..eb75699 100644 --- a/types/easymde.d.ts +++ b/types/easymde.d.ts @@ -221,6 +221,8 @@ declare namespace EasyMDE { imageUploadEndpoint?: string; imagePathAbsolute?: boolean; imageCSRFToken?: string; + imageCSRFName?: string; + imageCSRFHeader?: boolean; imageTexts?: ImageTextsOptions; errorMessages?: ImageErrorTextsOptions; errorCallback?: (errorMessage: string) => void;