Browse Source

Merge branch 'master' of github.com:Squidex/squidex

pull/1039/head
Sebastian 3 years ago
parent
commit
0e909f971a
  1. 16
      backend/src/Squidex.Web/Pipeline/FileCallbackResultExecutor.cs
  2. 32
      backend/src/Squidex/wwwroot/scripts/editor-sdk.d.ts
  3. 192
      backend/src/Squidex/wwwroot/scripts/editor-sdk.js

16
backend/src/Squidex.Web/Pipeline/FileCallbackResultExecutor.cs

@ -22,6 +22,11 @@ public sealed class FileCallbackResultExecutor : FileResultExecutorBase
public async Task ExecuteAsync(ActionContext context, FileCallbackResult result) public async Task ExecuteAsync(ActionContext context, FileCallbackResult result)
{ {
var response = context.HttpContext.Response;
// Always block execution of scripts and inline scripts for file downloads.
response.Headers[HeaderNames.ContentSecurityPolicy] = "script-src 'none'";
try try
{ {
var (range, _, serveBody) = SetHeadersAndLog(context, result, result.FileSize, result.FileSize != null); var (range, _, serveBody) = SetHeadersAndLog(context, result, result.FileSize, result.FileSize != null);
@ -32,14 +37,15 @@ public sealed class FileCallbackResultExecutor : FileResultExecutorBase
headerValue.SetHttpFileName(result.FileDownloadName); headerValue.SetHttpFileName(result.FileDownloadName);
context.HttpContext.Response.Headers[HeaderNames.ContentDisposition] = headerValue.ToString(); // This produces a nice file name without downloading it, but executes the file and shows images directly.
response.Headers[HeaderNames.ContentDisposition] = headerValue.ToString();
} }
if (serveBody) if (serveBody)
{ {
var bytesRange = new BytesRange(range?.From, range?.To); var bytesRange = new BytesRange(range?.From, range?.To);
await result.Callback(context.HttpContext.Response.Body, bytesRange, context.HttpContext.RequestAborted); await result.Callback(response.Body, bytesRange, context.HttpContext.RequestAborted);
} }
} }
catch (OperationCanceledException) catch (OperationCanceledException)
@ -50,8 +56,8 @@ public sealed class FileCallbackResultExecutor : FileResultExecutorBase
{ {
if (!context.HttpContext.Response.HasStarted && result.ErrorAs404) if (!context.HttpContext.Response.HasStarted && result.ErrorAs404)
{ {
context.HttpContext.Response.Headers.Clear(); response.Headers.Clear();
context.HttpContext.Response.StatusCode = 404; response.StatusCode = 404;
Logger.LogCritical(new EventId(99), e, "Failed to send result."); Logger.LogCritical(new EventId(99), e, "Failed to send result.");
} }
@ -61,4 +67,4 @@ public sealed class FileCallbackResultExecutor : FileResultExecutorBase
} }
} }
} }
} }

32
backend/src/Squidex/wwwroot/scripts/editor-sdk.d.ts

@ -1,4 +1,18 @@
type PluginOptions = {
/**
* Defines the accepted origins for incoming messages.
*/
acceptedOrigins?: string[];
}
declare class SquidexSidebar { declare class SquidexSidebar {
/**
* The constructor.
*
* @param options: The plugin options.
*/
constructor(options?: PluginOptions);
/** /**
* Get the current context. * Get the current context.
*/ */
@ -30,6 +44,13 @@ declare class SquidexSidebar {
} }
declare class SquidexWidget { declare class SquidexWidget {
/**
* The constructor.
*
* @param options: The plugin options.
*/
constructor(options?: PluginOptions);
/** /**
* Get the current context. * Get the current context.
*/ */
@ -41,6 +62,7 @@ declare class SquidexWidget {
* @param callback: The callback to invoke. * @param callback: The callback to invoke.
*/ */
onInit(callback: () => void): void; onInit(callback: () => void): void;
/** /**
* Clean the editor SDK. * Clean the editor SDK.
*/ */
@ -49,6 +71,13 @@ declare class SquidexWidget {
declare class SquidexFormField { declare class SquidexFormField {
/**
* The constructor.
*
* @param options: The plugin options.
*/
constructor(options?: PluginOptions);
/** /**
* Get the current value. * Get the current value.
*/ */
@ -152,6 +181,8 @@ declare class SquidexFormField {
* *
* @param schemas: The list of schema names. * @param schemas: The list of schema names.
* @param callback The callback to invoke when the dialog is completed or closed. * @param callback The callback to invoke when the dialog is completed or closed.
<<<<<<< HEAD
=======
* @param query: The initial query that is used in the UI. * @param query: The initial query that is used in the UI.
* @param selectedIds: The selected ids to mark them as selected in the content selector dialog. * @param selectedIds: The selected ids to mark them as selected in the content selector dialog.
*/ */
@ -159,6 +190,7 @@ declare class SquidexFormField {
/** /**
* Shows a dialog to pick a file. * Shows a dialog to pick a file.
>>>>>>> 8f149db852d984489e6ca1a07af988dac917ab56
*/ */
pickFile(): void; pickFile(): void;

192
backend/src/Squidex/wwwroot/scripts/editor-sdk.js

@ -53,13 +53,19 @@ function isArrayOfStrings(value) {
return true; return true;
} }
function SquidexSidebar() { /**
* Creates a new plugin for sidebars.
*
* @param {object} options with the accepted origins.
*/
function SquidexSidebar(options) {
var initHandler; var initHandler;
var initCalled = false; var initCalled = false;
var contentHandler; var contentHandler;
var content; var content;
var context; var context;
var timer; var timer;
var acceptedOrigins = options && isArrayOfStrings(options.acceptedOrigins) ? options.acceptedOrigins : null;
function raiseContentChanged() { function raiseContentChanged() {
if (contentHandler && content) { if (contentHandler && content) {
@ -75,19 +81,28 @@ function SquidexSidebar() {
} }
function eventListener(event) { function eventListener(event) {
if (event.source !== window) { if (acceptedOrigins && acceptedOrigins.indexOf(event.origin) < 0) {
var type = event.data.type; console.log('Origin not accepted: ' + event.origin);
return;
if (type === 'contentChanged') { }
content = event.data.content;
if (event.source === window) {
return;
}
raiseContentChanged(); var type = event.data.type;
} else if (type === 'init') {
context = event.data.context; if (type === 'contentChanged') {
content = event.data.content;
raiseInit(); raiseContentChanged();
} } else if (type === 'init') {
context = event.data.context;
raiseInit();
} }
console.log('Received Message: ' + type);
} }
window.addEventListener('message', eventListener, false); window.addEventListener('message', eventListener, false);
@ -156,10 +171,17 @@ function SquidexSidebar() {
return plugin; return plugin;
} }
function SquidexWidget() {
/**
* Creates a new plugin for widgets.
*
* @param {object} options with the accepted origins.
*/
function SquidexWidget(options) {
var initHandler; var initHandler;
var initCalled = false; var initCalled = false;
var context; var context;
var acceptedOrigins = options && isArrayOfStrings(options.acceptedOrigins) ? options.acceptedOrigins : null;
document.body.style.margin = '0'; document.body.style.margin = '0';
document.body.style.padding = '0'; document.body.style.padding = '0';
@ -172,15 +194,24 @@ function SquidexWidget() {
} }
function eventListener(event) { function eventListener(event) {
if (event.source !== window) { if (acceptedOrigins && acceptedOrigins.indexOf(event.origin) < 0) {
var type = event.data.type; console.log('Origin not accepted: ' + event.origin);
return;
if (type === 'init') { }
context = event.data.context;
raiseInit(); if (event.source === window) {
} return;
}
var type = event.data.type;
if (type === 'init') {
context = event.data.context;
raiseInit();
} }
console.log('Received Message: ' + type);
} }
window.addEventListener('message', eventListener, false); window.addEventListener('message', eventListener, false);
@ -219,7 +250,12 @@ function SquidexWidget() {
return plugin; return plugin;
} }
function SquidexFormField() { /**
* Creates a new plugin for form fields.
*
* @param {object} options with the accepted origins.
*/
function SquidexFormField(options) {
var context; var context;
var currentConfirm; var currentConfirm;
var currentPickAssets; var currentPickAssets;
@ -241,6 +277,7 @@ function SquidexFormField() {
var timer; var timer;
var value; var value;
var valueHandler; var valueHandler;
var acceptedOrigins = options && isArrayOfStrings(options.acceptedOrigins) ? options.acceptedOrigins : null;
function raiseInit() { function raiseInit() {
if (initHandler && !initCalled && context) { if (initHandler && !initCalled && context) {
@ -292,81 +329,88 @@ function SquidexFormField() {
} }
function eventListener(event) { function eventListener(event) {
if (event.source !== window) { if (acceptedOrigins && acceptedOrigins.indexOf(event.origin) < 0) {
var type = event.data.type; console.log('Origin not accepted: ' + event.origin);
return;
}
console.log('Received Message: ' + type); if (event.source === window) {
return;
}
var type = event.data.type;
if (type === 'disabled') { if (type === 'disabled') {
var newDisabled = event.data.isDisabled; var newDisabled = event.data.isDisabled;
if (disabled !== newDisabled) { if (disabled !== newDisabled) {
disabled = newDisabled; disabled = newDisabled;
raiseDisabled(); raiseDisabled();
} }
} else if (type === 'moved') { } else if (type === 'moved') {
var newIndex = event.data.index; var newIndex = event.data.index;
if (index !== newIndex) { if (index !== newIndex) {
index = newIndex; index = newIndex;
raisedMoved(); raisedMoved();
} }
} else if (type === 'languageChanged') { } else if (type === 'languageChanged') {
var newLanguage = event.data.language; var newLanguage = event.data.language;
if (language !== newLanguage) { if (language !== newLanguage) {
language = newLanguage; language = newLanguage;
raiseLanguageChanged(); raiseLanguageChanged();
} }
} else if (type === 'valueChanged') { } else if (type === 'valueChanged') {
value = event.data.value; value = event.data.value;
raiseValueChanged(); raiseValueChanged();
} else if (type === 'formValueChanged') { } else if (type === 'formValueChanged') {
formValue = event.data.formValue; formValue = event.data.formValue;
raiseFormValueChanged(); raiseFormValueChanged();
} else if (type === 'fullscreenChanged') { } else if (type === 'fullscreenChanged') {
fullscreen = event.data.fullscreen; fullscreen = event.data.fullscreen;
raiseFullscreen(); raiseFullscreen();
} else if (type === 'expandedChanged') { } else if (type === 'expandedChanged') {
expanded = event.data.expanded; expanded = event.data.expanded;
raiseExpanded(); raiseExpanded();
} else if (type === 'init') { } else if (type === 'init') {
context = event.data.context; context = event.data.context;
raiseInit(); raiseInit();
} else if (type === 'confirmResult') { } else if (type === 'confirmResult') {
var correlationId = event.data.correlationId; var correlationId = event.data.correlationId;
if (currentConfirm && currentConfirm.correlationId === correlationId) { if (currentConfirm && currentConfirm.correlationId === correlationId) {
if (typeof currentConfirm.callback === 'function') { if (typeof currentConfirm.callback === 'function') {
currentConfirm.callback(event.data.result); currentConfirm.callback(event.data.result);
}
} }
} else if (type === 'pickAssetsResult') { }
var correlationId = event.data.correlationId; } else if (type === 'pickAssetsResult') {
var correlationId = event.data.correlationId;
if (currentPickAssets && currentPickAssets.correlationId === correlationId) { if (currentPickAssets && currentPickAssets.correlationId === correlationId) {
if (typeof currentPickAssets.callback === 'function') { if (typeof currentPickAssets.callback === 'function') {
currentPickAssets.callback(event.data.result); currentPickAssets.callback(event.data.result);
}
} }
} else if (type === 'pickContentsResult') { }
var correlationId = event.data.correlationId; } else if (type === 'pickContentsResult') {
var correlationId = event.data.correlationId;
if (currentPickContents && currentPickContents.correlationId === correlationId) { if (currentPickContents && currentPickContents.correlationId === correlationId) {
if (typeof currentPickContents.callback === 'function') { if (typeof currentPickContents.callback === 'function') {
currentPickContents.callback(event.data.result); currentPickContents.callback(event.data.result);
}
} }
} }
} }
console.log('Received Message: ' + type);
} }
window.addEventListener('message', eventListener, false); window.addEventListener('message', eventListener, false);

Loading…
Cancel
Save