From 181fb0af93cc0f80f0e3a19def4acec5573227f3 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Leon=20B=C3=B6sche?= Date: Mon, 12 Jan 2026 01:47:52 +0100 Subject: [PATCH] Fix Collabora iframe loading and sandbox security - Reverted to direct iframe src approach instead of form submission - This avoids 'Form submission canceled' error - Removed allow-same-origin from sandbox to improve security - Added allow-popups-to-escape-sandbox for Collabora functionality - Use direct URL with WOPISrc parameter instead of POST form --- b0esche_cloud/lib/pages/document_viewer.dart | 67 ++++++-------------- 1 file changed, 20 insertions(+), 47 deletions(-) diff --git a/b0esche_cloud/lib/pages/document_viewer.dart b/b0esche_cloud/lib/pages/document_viewer.dart index 2f8e451..005167a 100644 --- a/b0esche_cloud/lib/pages/document_viewer.dart +++ b/b0esche_cloud/lib/pages/document_viewer.dart @@ -454,67 +454,40 @@ class _DocumentViewerModalState extends State { } Widget _buildCollaboraIframe(String collaboraUrl) { - // For Collabora Online, we need to use a form-based approach instead of iframe - // because loleaflet.html expects a POST request with WOPISrc in the body - - const String viewType = 'collabora-form-container'; + // For Collabora Online, create an iframe that loads the editor directly + const String viewType = 'collabora-iframe'; ui.platformViewRegistry.registerViewFactory( viewType, (int viewId) { - // Create a container div for the form and iframe - final container = html.DivElement() - ..style.width = '100%' - ..style.height = '100%' - ..style.margin = '0' - ..style.padding = '0'; - - // Create a hidden form to POST to Collabora - final form = html.FormElement() - ..method = 'POST' - ..action = 'https://of.b0esche.cloud/loleaflet/dist/loleaflet.html' - ..target = 'collabora-frame' - ..style.display = 'none'; - - // Extract the WOPISrc value from the URL - final wopisrcValue = collaboraUrl.split('WOPISrc=').length > 1 - ? collaboraUrl.split('WOPISrc=')[1] + // Extract the WOPISrc value + final wopisrcValue = collaboraUrl.contains('WOPISrc=') + ? Uri.decodeComponent(collaboraUrl.split('WOPISrc=')[1]) : ''; - final wopisrcInput = html.InputElement() - ..type = 'hidden' - ..name = 'WOPISrc' - ..value = wopisrcValue; - - form.append(wopisrcInput); - container.append(form); - // Create the iframe final iframe = html.IFrameElement() - ..name = 'collabora-frame' ..style.border = 'none' ..style.width = '100%' ..style.height = '100%' ..style.margin = '0' - ..style.padding = '0'; + ..style.padding = '0' + ..setAttribute( + 'allow', + 'microphone; camera; usb; autoplay; clipboard-read; clipboard-write', + ) + // Remove allow-same-origin and add allow-popups-to-escape-sandbox for better security + ..setAttribute( + 'sandbox', + 'allow-scripts allow-popups allow-forms allow-pointer-lock allow-presentation allow-modals allow-downloads allow-popups-to-escape-sandbox', + ); - // Set sandbox attributes - iframe.setAttribute( - 'sandbox', - 'allow-same-origin allow-scripts allow-popups allow-forms allow-top-navigation allow-pointer-lock allow-presentation allow-modals allow-downloads', - ); + // Build the full Collabora URL + final collaboraPath = + 'https://of.b0esche.cloud/loleaflet/dist/loleaflet.html'; + iframe.src = '$collaboraPath?WOPISrc=$wopisrcValue'; - iframe.setAttribute( - 'allow', - 'microphone; camera; usb; autoplay; clipboard-read; clipboard-write', - ); - - container.append(iframe); - - // Submit the form to load the document - form.submit(); - - return container; + return iframe; }, );