TYPO3 vulnerable to Cross-Site Scripting in the Form Manager Module
Description
TYPO3 is an enterprise content management system. Starting in version 9.0.0 and prior to versions 9.5.48 ELTS, 10.4.45 ELTS, 11.5.37 LTS, 12.4.15 LTS, and 13.1.1, the form manager backend module is vulnerable to cross-site scripting. Exploiting this vulnerability requires a valid backend user account with access to the form module. TYPO3 versions 9.5.48 ELTS, 10.4.45 ELTS, 11.5.37 LTS, 12.4.15 LTS, and 13.1.1 fix the problem described.
AI Insight
LLM-synthesized narrative grounded in this CVE's description and references.
TYPO3 Form Manager backend module is vulnerable to stored cross-site scripting via unsanitized form-related data, exploitable by authenticated backend users with form access.
Vulnerability
The Form Manager backend module in TYPO3 versions 9.0.0 through before 9.5.48 ELTS, 10.4.45 ELTS, 11.5.37 LTS, 12.4.15 LTS, and 13.1.1 contains a stored cross-site scripting (XSS) vulnerability. The bug originates from insufficient output encoding when the module dynamically builds HTML for displaying form references. Specifically, user-controllable values such as the form name, record page title, record edit URL, record title, record UID, and form persistence identifier are concatenated into HTML strings without prior sanitization or escaping [3][4]. The patches show that each of these values now passes through securityUtility.encodeHtml() before insertion into the HTML [3][4].
Exploitation
Exploiting this vulnerability requires a valid backend user account that has been granted access to the Form module [2]. An attacker with such privileges can craft or manipulate form-related data—for instance, by creating a form with a malicious name or by injecting payloads into record fields that are later displayed in the Form Manager's reference list. When the victim (another backend user) views the affected section in the Form Manager, the injected script executes in the context of that user's browser session. No additional network position or privileges are needed beyond the initial authenticated access to the Form module.
Impact
A successful XSS attack allows the attacker to execute arbitrary JavaScript in the context of the victim's backend session. This could lead to session hijacking, unauthorized administrative actions, data theft, or defacement of the TYPO3 backend interface. Since the vulnerability resides in the backend, the attacker could potentially escalate privileges by leveraging the victim's permissions.
Mitigation
TYPO3 has released patched versions that fix the issue: 9.5.48 ELTS, 10.4.45 ELTS, 11.5.37 LTS, 12.4.15 LTS, and 13.1.1 [2]. All users running an affected version should upgrade immediately. No workarounds have been published, so updating is the recommended course of action.
AI Insight generated on May 20, 2026. Synthesized from this CVE's description and the cited reference URLs; citations are validated against the source bundle.
Affected packages
Versions sourced from the GitHub Security Advisory.
| Package | Affected versions | Patched versions |
|---|---|---|
typo3/cms-corePackagist | >= 9.0.0, < 9.5.48 | 9.5.48 |
typo3/cms-corePackagist | >= 10.0.0, < 10.4.45 | 10.4.45 |
typo3/cms-corePackagist | >= 11.0.0, < 11.5.37 | 11.5.37 |
typo3/cms-corePackagist | >= 12.0.0, < 12.4.15 | 12.4.15 |
typo3/cms-corePackagist | >= 13.0.0, < 13.1.1 | 13.1.1 |
Affected products
2Patches
32832e2f51f92[SECURITY] Prevent XSS in FormManager backend module
3 files changed · +8 −6
Build/Sources/TypeScript/form/backend/form-manager/view-model.ts+5 −5 modified@@ -711,7 +711,7 @@ function showReferencesSetup(formManagerApp: FormManager): void { const referencesLength = data.references.length; if (referencesLength > 0) { html = '<div>' - + '<h3>' + TYPO3.lang['formManager.references.headline'].replace('{0}', $that.data('formName')) + '</h3>' + + '<h3>' + TYPO3.lang['formManager.references.headline'].replace('{0}', securityUtility.encodeHtml($that.data('formName'))) + '</h3>' + '</div>' + '<div class="table-fit">' + '<table id="forms" class="table table-striped table-sm">' @@ -725,11 +725,11 @@ function showReferencesSetup(formManagerApp: FormManager): void { for (let i = 0, len = data.references.length; i < len; ++i) { html += '<tr>' - + '<td>' + data.references[i].recordPageTitle + '</td>' + + '<td>' + securityUtility.encodeHtml(data.references[i].recordPageTitle) + '</td>' + '<td>' + data.references[i].recordIcon - + '<a href="' + data.references[i].recordEditUrl + '" data-identifier="referenceLink">' - + data.references[i].recordTitle + ' (uid: ' + data.references[i].recordUid + ')' + + '<a href="' + securityUtility.encodeHtml(data.references[i].recordEditUrl) + '" data-identifier="referenceLink">' + + securityUtility.encodeHtml(data.references[i].recordTitle) + ' (uid: ' + securityUtility.encodeHtml(data.references[i].recordUid) + ')' + '</a>' + '</td>' + '</tr>'; @@ -740,7 +740,7 @@ function showReferencesSetup(formManagerApp: FormManager): void { + '</div>'; } else { html = '<div>' - + '<h1>' + TYPO3.lang['formManager.references.title'].replace('{0}', data.formPersistenceIdentifier) + '</h1>' + + '<h1>' + TYPO3.lang['formManager.references.title'].replace('{0}', securityUtility.encodeHtml(data.formPersistenceIdentifier)) + '</h1>' + '</div>' + '<div>' + TYPO3.lang['formManager.no_references'] + '</div>'; }
typo3/sysext/form/Classes/Controller/FormManagerController.php+2 −0 modified@@ -158,6 +158,7 @@ protected function createAction(string $formName, string $templatePath, string $ 'url' => $this->uriBuilder->uriFor('index', ['formPersistenceIdentifier' => $formPersistenceIdentifier], 'FormEditor'), ]; + $form = ArrayUtility::stripTagsFromValuesRecursive($form); try { $this->formPersistenceManager->save($formPersistenceIdentifier, $form); } catch (PersistenceManagerException $e) { @@ -222,6 +223,7 @@ protected function duplicateAction(string $formName, string $formPersistenceIden 'url' => $this->uriBuilder->uriFor('index', ['formPersistenceIdentifier' => $formPersistenceIdentifier], 'FormEditor'), ]; + $formToDuplicate = ArrayUtility::stripTagsFromValuesRecursive($formToDuplicate); try { $this->formPersistenceManager->save($formPersistenceIdentifier, $formToDuplicate); } catch (PersistenceManagerException $e) {
typo3/sysext/form/Resources/Public/JavaScript/backend/form-manager/view-model.js+1 −1 modified@@ -10,4 +10,4 @@ * * The TYPO3 project - inspiring people to share! */ -import $ from"jquery";import Modal from"@typo3/backend/modal.js";import Severity from"@typo3/backend/severity.js";import MultiStepWizard from"@typo3/backend/multi-step-wizard.js";import Icons from"@typo3/backend/icons.js";import Notification from"@typo3/backend/notification.js";import SecurityUtility from"@typo3/core/security-utility.js";import{selector}from"@typo3/core/literals.js";const securityUtility=new SecurityUtility;var Identifiers;function newFormSetup(e){$(Identifiers.newFormModalTrigger).on("click",(function(t){t.preventDefault(),MultiStepWizard.addSlide("new-form-step-1",TYPO3.lang["formManager.newFormWizard.step1.title"],"",Severity.info,TYPO3.lang["formManager.newFormWizard.step1.progressLabel"],(async function(t){const a=await Icons.getIcon("actions-plus",Icons.sizes.small),r=await Icons.getIcon("form-page",Icons.sizes.large),i=await Icons.getIcon("apps-pagetree-page-default",Icons.sizes.large);let o;const n=MultiStepWizard.setup.$carousel.closest(".modal"),l=n.find(".modal-footer").find('button[name="next"]');MultiStepWizard.blurCancelStep(),MultiStepWizard.lockNextStep(),MultiStepWizard.lockPrevStep();0===e.getAccessibleFormStorageFolders().length&&(o='<div class="new-form-modal"><div class="row"><label class="col col-form-label">'+TYPO3.lang["formManager.newFormWizard.step1.noStorages"]+"</label></div></div>",t.html(o),e.assert(!1,"No accessible form storage folders",1477506500)),o='<div class="new-form-modal">',o+='<div class="card-container"><div class="card card-size-medium"><div class="card-header"><div class="card-icon">'+i+'</div><div class="card-header-body"><h2 class="card-title">'+TYPO3.lang["formManager.blankForm.label"]+'</h2><span class="card-subtitle">'+TYPO3.lang["formManager.blankForm.subtitle"]+'</span></div></div><div class="card-body"><p class="card-text">'+TYPO3.lang["formManager.blankForm.description"]+'</p></div><div class="card-footer"><button type="button" class="btn btn-success" data-inline="1" value="blank" data-identifier="newFormModeButton">'+a+" "+TYPO3.lang["formManager.blankForm.label"]+'</button></div></div><div class="card card-size-medium"><div class="card-header"><div class="card-icon">'+r+'</div><div class="card-header-body"><h2 class="card-title">'+TYPO3.lang["formManager.predefinedForm.label"]+'</h2><span class="card-subtitle">'+TYPO3.lang["formManager.predefinedForm.subtitle"]+'</span></div></div><div class="card-body"><p class="card-text">'+TYPO3.lang["formManager.predefinedForm.description"]+'</p></div><div class="card-footer"><button type="button" class="btn btn-success" data-inline="1" value="predefined" data-identifier="newFormModeButton">'+a+" "+TYPO3.lang["formManager.predefinedForm.label"]+"</button></div></div>",o+="</div>",t.html(o),$(Identifiers.newFormModeButton,n).on("click",(function(e){MultiStepWizard.set("newFormMode",$(e.currentTarget).val()),MultiStepWizard.next()})),l.on("click",(async function(){t.html($("<div />",{class:"text-center"}).append(await Icons.getIcon("spinner-circle",Icons.sizes.default,null,null)).prop("outerHTML"))}))})),MultiStepWizard.addSlide("new-form-step-2",TYPO3.lang["formManager.newFormWizard.step2.title"],"",Severity.info,top.TYPO3.lang["wizard.progressStep.configure"],(function(t,a){let r,i;MultiStepWizard.lockNextStep(),MultiStepWizard.unlockPrevStep();const o=MultiStepWizard.setup.$carousel.closest(".modal"),n=o.find(".modal-footer").find('button[name="next"]'),l=e.getAccessibleFormStorageFolders();if(a.savePath||(MultiStepWizard.set("savePath",l[0].value),MultiStepWizard.set("savePathName",l[0].label)),l.length>1){i=$('<select class="new-form-save-path form-select" id="new-form-save-path" data-identifier="newFormSavePath" />');for(let e=0,t=l.length;e<t;++e){const t=new Option(l[e].label,l[e].value);$(i).append(t)}}const s=e.getPrototypes();e.assert(s.length>0,"No prototypes available",1477506501),a.prototypeName||(MultiStepWizard.set("prototypeName",s[0].value),MultiStepWizard.set("prototypeNameName",s[0].label));const d=$('<select class="new-form-prototype-name form-select" id="new-form-prototype-name" data-identifier="newFormPrototypeName" />');for(let e=0,t=s.length;e<t;++e){const t=new Option(s[e].label,s[e].value);$(d).append(t)}let c=e.getTemplatesForPrototype(s[0].value);e.assert(c.length>0,"No templates available",1477506502),a.templatePath||(MultiStepWizard.set("templatePath",c[0].value),MultiStepWizard.set("templatePathName",c[0].label));const m=$('<select class="new-form-template form-select" id="new-form-template" data-identifier="newFormTemplate" />');for(let e=0,t=c.length;e<t;++e){const t=new Option(c[e].label,c[e].value);$(m).append(t)}r='<div class="new-form-modal">',"blank"===a.newFormMode?(r+='<h5 class="form-section-headline">'+TYPO3.lang["formManager.blankForm.label"]+"</h5>",MultiStepWizard.set("templatePath","EXT:form/Resources/Private/Backend/Templates/FormEditor/Yaml/NewForms/BlankForm.yaml"),MultiStepWizard.set("templatePathName",TYPO3.lang["formManager.blankForm.label"])):(r+='<h5 class="form-section-headline">'+TYPO3.lang["formManager.predefinedForm.label"]+"</h5>",s.length>1&&(r+='<div class="mb-3"><label for="new-form-prototype-name"><strong>'+TYPO3.lang["formManager.form_prototype"]+'</strong></label><div class="formengine-field-item t3js-formengine-field-item"><div class="form-control-wrap">'+$(d)[0].outerHTML+"</div></div></div>"),c.length>1&&(r+='<div class="mb-3"><label for="new-form-template"><strong>'+TYPO3.lang["formManager.form_template"]+'</strong></label><div class="formengine-field-item t3js-formengine-field-item"><div class="form-description">'+TYPO3.lang["formManager.form_template_description"]+'</div><div class="form-control-wrap">'+$(m)[0].outerHTML+"</div></div></div>")),r+='<div class="mb-3"><label for="new-form-name"><strong>'+TYPO3.lang["formManager.form_name"]+'</strong></label><div class="formengine-field-item t3js-formengine-field-item"><div class="form-description">'+TYPO3.lang["formManager.form_name_description"]+'</div><div class="form-control-wrap">',a.formName?(r+='<input class="form-control" id="new-form-name" data-identifier="newFormName" value="'+securityUtility.encodeHtml(a.formName)+'" />',setTimeout((function(){MultiStepWizard.unlockNextStep()}),200)):r+='<input class="form-control has-error" id="new-form-name" data-identifier="newFormName" />',r+="</div></div></div>",i&&(r+='<div class="mb-3"><label for="new-form-save-path"><strong>'+TYPO3.lang["formManager.form_save_path"]+'</strong></label><div class="formengine-field-item t3js-formengine-field-item"><div class="form-description">'+TYPO3.lang["formManager.form_save_path_description"]+'</div><div class="form-control-wrap">'+$(i)[0].outerHTML+"</div></div></div>"),r+="</div>",t.html(r),a.savePath&&$(Identifiers.newFormSavePath,o).val(a.savePath),a.templatePath&&$(Identifiers.newFormTemplate,o).val(a.templatePath),s.length>1?$(Identifiers.newFormPrototypeName,o).focus():c.length>1&&$(Identifiers.newFormTemplate,o).focus();const p=function(){$(Identifiers.newFormTemplate,o).on("change",(function(){MultiStepWizard.set("templatePath",$(Identifiers.newFormTemplate+" option:selected",o).val()),MultiStepWizard.set("templatePathName",$(Identifiers.newFormTemplate+" option:selected",o).text()),MultiStepWizard.set("templatePathOnPrev",$(Identifiers.newFormTemplate+" option:selected",o).val())}))};$(Identifiers.newFormPrototypeName,o).on("change",(function(t){MultiStepWizard.set("prototypeName",$(Identifiers.newFormPrototypeName+" option:selected",o).val()),MultiStepWizard.set("prototypeNameName",$(Identifiers.newFormPrototypeName+" option:selected",o).text()),c=e.getTemplatesForPrototype($(t.currentTarget).val()),$(Identifiers.newFormTemplate,o).off().empty();for(let e=0,t=c.length;e<t;++e){const t=new Option(c[e].label,c[e].value);$(Identifiers.newFormTemplate,o).append(t),MultiStepWizard.set("templatePath",c[0].value),MultiStepWizard.set("templatePathName",c[0].label)}p()})),p(),a.prototypeName&&($(Identifiers.newFormPrototypeName,o).val(a.prototypeName),$(Identifiers.newFormPrototypeName,o).trigger("change"),a.templatePathOnPrev&&($(Identifiers.newFormTemplate,o).find(selector`option[value="${a.templatePathOnPrev}"]`).prop("selected",!0),$(Identifiers.newFormTemplate,o).trigger("change"))),$(Identifiers.newFormName,o).focus(),$(Identifiers.newFormName,o).on("keyup paste",(function(e){$(e.currentTarget).val().length>0?($(e.currentTarget).removeClass("has-error"),MultiStepWizard.unlockNextStep(),MultiStepWizard.set("formName",$(e.currentTarget).val()),"code"in e&&"Enter"===e.code&&MultiStepWizard.triggerStepButton("next")):($(e.currentTarget).addClass("has-error"),MultiStepWizard.lockNextStep())})),$(Identifiers.newFormSavePath,o).on("change",(function(){MultiStepWizard.set("savePath",$(Identifiers.newFormSavePath+" option:selected",o).val()),MultiStepWizard.set("savePathName",$(Identifiers.newFormSavePath+" option:selected",o).text())})),"blank"===a.newFormMode||a.templatePathName||MultiStepWizard.set("templatePathName",$(Identifiers.newFormTemplate+" option:selected",o).text()),n.on("click",(async function(){MultiStepWizard.setup.forceSelection=!1,t.html($("<div />",{class:"text-center"}).append(await Icons.getIcon("spinner-circle",Icons.sizes.default,null,null)).prop("outerHTML"))}))})),MultiStepWizard.addSlide("new-form-step-3",TYPO3.lang["formManager.newFormWizard.step3.title"],"",Severity.info,TYPO3.lang["formManager.newFormWizard.step3.progressLabel"],(async function(e,t){const a=await Icons.getIcon("actions-cog",Icons.sizes.small),r=await Icons.getIcon("actions-file-t3d",Icons.sizes.small),i=await Icons.getIcon("actions-tag",Icons.sizes.small),o=await Icons.getIcon("actions-database",Icons.sizes.small),n=MultiStepWizard.setup.$carousel.closest(".modal").find(".modal-footer").find('button[name="next"]');let l='<div class="new-form-modal">';l+='<div class="mb-3"><h5 class="form-section-headline">'+TYPO3.lang["formManager.newFormWizard.step3.check"]+"</h5><p>"+TYPO3.lang["formManager.newFormWizard.step3.message"]+'</p></div><div class="alert alert-notice"><div class="alert-body mt-1">',t.prototypeNameName&&(l+='<div class="row my-1"><div class="col col-sm-6">'+a+" "+TYPO3.lang["formManager.form_prototype"]+'</div><div class="col">'+securityUtility.encodeHtml(t.prototypeNameName)+"</div></div>"),t.templatePathName&&(l+='<div class="row my-1"><div class="col col-sm-6">'+r+" "+TYPO3.lang["formManager.form_template"]+'</div><div class="col">'+securityUtility.encodeHtml(t.templatePathName)+"</div></div>"),l+='<div class="row my-1"><div class="col col-sm-6">'+i+" "+TYPO3.lang["formManager.form_name"]+'</div><div class="col">'+securityUtility.encodeHtml(t.formName)+'</div></div><div class="row my-1"><div class="col col-sm-6">'+o+" "+TYPO3.lang["formManager.form_save_path"]+'</div><div class="col">'+securityUtility.encodeHtml(t.savePathName)+"</div></div>",l+="</div></div></div>",e.html(l),n.focus(),n.on("click",(async function(){MultiStepWizard.setup.forceSelection=!1,e.html($("<div />",{class:"text-center"}).append(await Icons.getIcon("spinner-circle",Icons.sizes.default,null,null)).prop("outerHTML"))}))})),MultiStepWizard.addFinalProcessingSlide((function(){$.post(e.getAjaxEndpoint("create"),{formName:MultiStepWizard.setup.settings.formName,templatePath:MultiStepWizard.setup.settings.templatePath,prototypeName:MultiStepWizard.setup.settings.prototypeName,savePath:MultiStepWizard.setup.settings.savePath},(function(e){"success"===e.status?document.location=e.url:Notification.error(TYPO3.lang["formManager.newFormWizard.step4.errorTitle"],TYPO3.lang["formManager.newFormWizard.step4.errorMessage"]+" "+e.message),MultiStepWizard.dismiss()})).fail((function(e,t,a){const r=(new DOMParser).parseFromString(e.responseText,"text/html"),i=$(r.body);Notification.error(t,a,2),MultiStepWizard.dismiss(),$(Identifiers.t3Logo,i).remove(),$(Identifiers.t3Footer,i).remove(),$(Identifiers.moduleBody).html(i.html())}))})).then((function(){MultiStepWizard.show()}))}))}function removeFormSetup(e){$(Identifiers.removeFormModalTrigger).on("click",(function(t){const a=[];t.preventDefault();const r=$(t.currentTarget);a.push({text:TYPO3.lang["formManager.cancel"],active:!0,btnClass:"btn-default",name:"cancel",trigger:function(e,t){t.hideModal()}}),a.push({text:TYPO3.lang["formManager.remove_form"],active:!0,btnClass:"btn-warning",name:"createform",trigger:function(t,a){document.location=e.getAjaxEndpoint("delete")+"&formPersistenceIdentifier="+r.data("formPersistenceIdentifier"),a.hideModal()}}),Modal.show(TYPO3.lang["formManager.remove_form_title"],TYPO3.lang["formManager.remove_form_message"],Severity.warning,a)}))}function duplicateFormSetup(e){$(Identifiers.duplicateFormModalTrigger).on("click",(function(t){t.preventDefault();const a=$(t.currentTarget);MultiStepWizard.addSlide("duplicate-form-step-1",TYPO3.lang["formManager.duplicateFormWizard.step1.title"].replace("{0}",a.data("formName")),"",Severity.info,top.TYPO3.lang["wizard.progressStep.configure"],(function(t){let r,i;MultiStepWizard.lockPrevStep(),MultiStepWizard.lockNextStep();const o=MultiStepWizard.setup.$carousel.closest(".modal"),n=o.find(".modal-footer").find('button[name="next"]'),l=e.getAccessibleFormStorageFolders();if(e.assert(l.length>0,"No accessible form storage folders",1477649539),MultiStepWizard.set("formPersistenceIdentifier",a.data("formPersistenceIdentifier")),MultiStepWizard.set("savePath",l[0].value),l.length>1){i=$('<select id="duplicate-form-save-path" class="form-select" data-identifier="duplicateFormSavePath" />');for(let e=0,t=l.length;e<t;++e){const t=new Option(l[e].label,l[e].value);$(i).append(t)}}r='<div class="duplicate-form-modal"><h5 class="form-section-headline">'+TYPO3.lang["formManager.new_form_name"]+'</h5><div class="mb-3"><label for="duplicate-form-name"><strong>'+TYPO3.lang["formManager.form_name"]+'</strong></label><div class="formengine-field-item t3js-formengine-field-item"><div class="form-description">'+TYPO3.lang["formManager.form_name_description"]+'</div><div class="form-control-wrap"><input id="duplicate-form-name" class="form-control has-error" data-identifier="duplicateFormName" /></div></div></div>',i&&(r+='<div class="mb-3"><label for="duplicate-form-save-path"><strong>'+TYPO3.lang["formManager.form_save_path"]+'</strong></label><div class="formengine-field-item t3js-formengine-field-item"><div class="form-description">'+TYPO3.lang["formManager.form_save_path_description"]+'</div><div class="form-control-wrap">'+$(i)[0].outerHTML+"</div></div></div>"),r+="</div>",t.html(r),$(Identifiers.duplicateFormName,o).focus(),$(Identifiers.duplicateFormName,o).on("keyup paste",(function(e){const t=$(event.currentTarget);t.val().length>0?(t.removeClass("has-error"),MultiStepWizard.unlockNextStep(),MultiStepWizard.set("formName",t.val()),"code"in e&&"Enter"===e.code&&MultiStepWizard.triggerStepButton("next")):(t.addClass("has-error"),MultiStepWizard.lockNextStep())})),n.on("click",(async function(){MultiStepWizard.setup.forceSelection=!1,MultiStepWizard.set("confirmationDuplicateFormName",a.data("formName")),l.length>1?(MultiStepWizard.set("savePath",$(Identifiers.duplicateFormSavePath+" option:selected",o).val()),MultiStepWizard.set("confirmationDuplicateFormSavePath",$(Identifiers.duplicateFormSavePath+" option:selected",o).text())):(MultiStepWizard.set("savePath",l[0].value),MultiStepWizard.set("confirmationDuplicateFormSavePath",l[0].label)),t.html($("<div />",{class:"text-center"}).append(await Icons.getIcon("spinner-circle",Icons.sizes.default,null,null)).prop("outerHTML"))}))})),MultiStepWizard.addSlide("duplicate-form-step-2",TYPO3.lang["formManager.duplicateFormWizard.step2.title"],"",Severity.info,TYPO3.lang["formManager.duplicateFormWizard.step2.progressLabel"],(async function(e,t){const a=await Icons.getIcon("actions-file-t3d",Icons.sizes.small),r=await Icons.getIcon("actions-tag",Icons.sizes.small),i=await Icons.getIcon("actions-database",Icons.sizes.small);MultiStepWizard.unlockPrevStep(),MultiStepWizard.unlockNextStep();const o=MultiStepWizard.setup.$carousel.closest(".modal").find(".modal-footer").find('button[name="next"]');let n='<div class="new-form-modal"><div class="row"><div class="col">';n+='<div class="mb-3"><h5 class="form-section-headline">'+TYPO3.lang["formManager.duplicateFormWizard.step2.check"]+"</h5><p>"+TYPO3.lang["formManager.newFormWizard.step3.message"]+'</p></div><div class="alert alert-notice"><div class="alert-body mt-1"><div class="dropdown-table-row"><div class="dropdown-table-column dropdown-table-icon">'+a+'</div><div class="dropdown-table-column dropdown-table-title">'+TYPO3.lang["formManager.form_copied"]+'</div><div class="dropdown-table-column dropdown-table-value">'+securityUtility.encodeHtml(t.confirmationDuplicateFormName)+'</div></div><div class="dropdown-table-row"><div class="dropdown-table-column dropdown-table-icon">'+r+'</div><div class="dropdown-table-column dropdown-table-title">'+TYPO3.lang["formManager.form_name"]+'</div><div class="dropdown-table-column dropdown-table-value">'+securityUtility.encodeHtml(t.formName)+'</div></div><div class="dropdown-table-row"><div class="dropdown-table-column dropdown-table-icon">'+i+'</div><div class="dropdown-table-column dropdown-table-title">'+TYPO3.lang["formManager.form_save_path"]+'</div><div class="dropdown-table-column dropdown-table-value">'+securityUtility.encodeHtml(t.confirmationDuplicateFormSavePath)+"</div></div></div></div>",n+="</div></div></div>",e.html(n),o.focus(),o.on("click",(async function(){MultiStepWizard.setup.forceSelection=!1,e.html($("<div />",{class:"text-center"}).append(await Icons.getIcon("spinner-circle",Icons.sizes.default,null,null)).prop("outerHTML"))}))})),MultiStepWizard.addFinalProcessingSlide((function(){$.post(e.getAjaxEndpoint("duplicate"),{formName:MultiStepWizard.setup.settings.formName,formPersistenceIdentifier:MultiStepWizard.setup.settings.formPersistenceIdentifier,savePath:MultiStepWizard.setup.settings.savePath},(function(e){"success"===e.status?document.location=e.url:Notification.error(TYPO3.lang["formManager.duplicateFormWizard.step3.errorTitle"],TYPO3.lang["formManager.duplicateFormWizard.step3.errorMessage"]+" "+e.message),MultiStepWizard.dismiss()})).fail((function(e,t,a){const r=(new DOMParser).parseFromString(e.responseText,"text/html"),i=$(r.body);Notification.error(t,a,2),MultiStepWizard.dismiss(),$(Identifiers.t3Logo,i).remove(),$(Identifiers.t3Footer,i).remove(),$(Identifiers.moduleBody).html(i.html())}))})).then((function(){MultiStepWizard.show()}))}))}function showReferencesSetup(e){$(Identifiers.showReferences).on("click",(t=>{t.preventDefault();const a=$(t.currentTarget),r=e.getAjaxEndpoint("references")+"&formPersistenceIdentifier="+a.data("formPersistenceIdentifier");$.get(r,(function(e){let t;const r=[];r.push({text:TYPO3.lang["formManager.cancel"],active:!0,btnClass:"btn-default",name:"cancel",trigger:function(e,t){t.hideModal()}});if(e.references.length>0){t="<div><h3>"+TYPO3.lang["formManager.references.headline"].replace("{0}",a.data("formName"))+'</h3></div><div class="table-fit"><table id="forms" class="table table-striped table-sm"><thead><tr><th>'+TYPO3.lang["formManager.page"]+"</th><th>"+TYPO3.lang["formManager.record"]+"</th></tr></thead><tbody>";for(let a=0,r=e.references.length;a<r;++a)t+="<tr><td>"+e.references[a].recordPageTitle+"</td><td>"+e.references[a].recordIcon+'<a href="'+e.references[a].recordEditUrl+'" data-identifier="referenceLink">'+e.references[a].recordTitle+" (uid: "+e.references[a].recordUid+")</a></td></tr>";t+="</tbody></table></div>"}else t="<div><h1>"+TYPO3.lang["formManager.references.title"].replace("{0}",e.formPersistenceIdentifier)+"</h1></div><div>"+TYPO3.lang["formManager.no_references"]+"</div>";t=$(t),$(Identifiers.referenceLink,t).on("click",(function(e){e.preventDefault(),Modal.currentModal.hideModal(),document.location=$(e.currentTarget).prop("href")})),Modal.show(TYPO3.lang["formManager.references.title"],t,Severity.info,r)})).fail((function(e,t,a){0!==e.status&&Notification.error(t,a,2)}))}))}!function(e){e.newFormModalTrigger='[data-identifier="newForm"]',e.duplicateFormModalTrigger='[data-identifier="duplicateForm"]',e.removeFormModalTrigger='[data-identifier="removeForm"]',e.newFormModeButton='[data-identifier="newFormModeButton"]',e.newFormName='[data-identifier="newFormName"]',e.newFormSavePath='[data-identifier="newFormSavePath"]',e.newFormPrototypeName='[data-identifier="newFormPrototypeName"]',e.newFormTemplate='[data-identifier="newFormTemplate"]',e.duplicateFormName='[data-identifier="duplicateFormName"]',e.duplicateFormSavePath='[data-identifier="duplicateFormSavePath"]',e.showReferences='[data-identifier="showReferences"]',e.referenceLink='[data-identifier="referenceLink"]',e.moduleBody=".module-body.t3js-module-body",e.t3Logo=".t3-message-page-logo",e.t3Footer="#t3-footer"}(Identifiers||(Identifiers={}));export function bootstrap(e){removeFormSetup(e),newFormSetup(e),duplicateFormSetup(e),showReferencesSetup(e)} \ No newline at end of file +import $ from"jquery";import Modal from"@typo3/backend/modal.js";import Severity from"@typo3/backend/severity.js";import MultiStepWizard from"@typo3/backend/multi-step-wizard.js";import Icons from"@typo3/backend/icons.js";import Notification from"@typo3/backend/notification.js";import SecurityUtility from"@typo3/core/security-utility.js";import{selector}from"@typo3/core/literals.js";const securityUtility=new SecurityUtility;var Identifiers;function newFormSetup(e){$(Identifiers.newFormModalTrigger).on("click",(function(t){t.preventDefault(),MultiStepWizard.addSlide("new-form-step-1",TYPO3.lang["formManager.newFormWizard.step1.title"],"",Severity.info,TYPO3.lang["formManager.newFormWizard.step1.progressLabel"],(async function(t){const a=await Icons.getIcon("actions-plus",Icons.sizes.small),r=await Icons.getIcon("form-page",Icons.sizes.large),i=await Icons.getIcon("apps-pagetree-page-default",Icons.sizes.large);let o;const n=MultiStepWizard.setup.$carousel.closest(".modal"),l=n.find(".modal-footer").find('button[name="next"]');MultiStepWizard.blurCancelStep(),MultiStepWizard.lockNextStep(),MultiStepWizard.lockPrevStep();0===e.getAccessibleFormStorageFolders().length&&(o='<div class="new-form-modal"><div class="row"><label class="col col-form-label">'+TYPO3.lang["formManager.newFormWizard.step1.noStorages"]+"</label></div></div>",t.html(o),e.assert(!1,"No accessible form storage folders",1477506500)),o='<div class="new-form-modal">',o+='<div class="card-container"><div class="card card-size-medium"><div class="card-header"><div class="card-icon">'+i+'</div><div class="card-header-body"><h2 class="card-title">'+TYPO3.lang["formManager.blankForm.label"]+'</h2><span class="card-subtitle">'+TYPO3.lang["formManager.blankForm.subtitle"]+'</span></div></div><div class="card-body"><p class="card-text">'+TYPO3.lang["formManager.blankForm.description"]+'</p></div><div class="card-footer"><button type="button" class="btn btn-success" data-inline="1" value="blank" data-identifier="newFormModeButton">'+a+" "+TYPO3.lang["formManager.blankForm.label"]+'</button></div></div><div class="card card-size-medium"><div class="card-header"><div class="card-icon">'+r+'</div><div class="card-header-body"><h2 class="card-title">'+TYPO3.lang["formManager.predefinedForm.label"]+'</h2><span class="card-subtitle">'+TYPO3.lang["formManager.predefinedForm.subtitle"]+'</span></div></div><div class="card-body"><p class="card-text">'+TYPO3.lang["formManager.predefinedForm.description"]+'</p></div><div class="card-footer"><button type="button" class="btn btn-success" data-inline="1" value="predefined" data-identifier="newFormModeButton">'+a+" "+TYPO3.lang["formManager.predefinedForm.label"]+"</button></div></div>",o+="</div>",t.html(o),$(Identifiers.newFormModeButton,n).on("click",(function(e){MultiStepWizard.set("newFormMode",$(e.currentTarget).val()),MultiStepWizard.next()})),l.on("click",(async function(){t.html($("<div />",{class:"text-center"}).append(await Icons.getIcon("spinner-circle",Icons.sizes.default,null,null)).prop("outerHTML"))}))})),MultiStepWizard.addSlide("new-form-step-2",TYPO3.lang["formManager.newFormWizard.step2.title"],"",Severity.info,top.TYPO3.lang["wizard.progressStep.configure"],(function(t,a){let r,i;MultiStepWizard.lockNextStep(),MultiStepWizard.unlockPrevStep();const o=MultiStepWizard.setup.$carousel.closest(".modal"),n=o.find(".modal-footer").find('button[name="next"]'),l=e.getAccessibleFormStorageFolders();if(a.savePath||(MultiStepWizard.set("savePath",l[0].value),MultiStepWizard.set("savePathName",l[0].label)),l.length>1){i=$('<select class="new-form-save-path form-select" id="new-form-save-path" data-identifier="newFormSavePath" />');for(let e=0,t=l.length;e<t;++e){const t=new Option(l[e].label,l[e].value);$(i).append(t)}}const s=e.getPrototypes();e.assert(s.length>0,"No prototypes available",1477506501),a.prototypeName||(MultiStepWizard.set("prototypeName",s[0].value),MultiStepWizard.set("prototypeNameName",s[0].label));const d=$('<select class="new-form-prototype-name form-select" id="new-form-prototype-name" data-identifier="newFormPrototypeName" />');for(let e=0,t=s.length;e<t;++e){const t=new Option(s[e].label,s[e].value);$(d).append(t)}let c=e.getTemplatesForPrototype(s[0].value);e.assert(c.length>0,"No templates available",1477506502),a.templatePath||(MultiStepWizard.set("templatePath",c[0].value),MultiStepWizard.set("templatePathName",c[0].label));const m=$('<select class="new-form-template form-select" id="new-form-template" data-identifier="newFormTemplate" />');for(let e=0,t=c.length;e<t;++e){const t=new Option(c[e].label,c[e].value);$(m).append(t)}r='<div class="new-form-modal">',"blank"===a.newFormMode?(r+='<h5 class="form-section-headline">'+TYPO3.lang["formManager.blankForm.label"]+"</h5>",MultiStepWizard.set("templatePath","EXT:form/Resources/Private/Backend/Templates/FormEditor/Yaml/NewForms/BlankForm.yaml"),MultiStepWizard.set("templatePathName",TYPO3.lang["formManager.blankForm.label"])):(r+='<h5 class="form-section-headline">'+TYPO3.lang["formManager.predefinedForm.label"]+"</h5>",s.length>1&&(r+='<div class="mb-3"><label for="new-form-prototype-name"><strong>'+TYPO3.lang["formManager.form_prototype"]+'</strong></label><div class="formengine-field-item t3js-formengine-field-item"><div class="form-control-wrap">'+$(d)[0].outerHTML+"</div></div></div>"),c.length>1&&(r+='<div class="mb-3"><label for="new-form-template"><strong>'+TYPO3.lang["formManager.form_template"]+'</strong></label><div class="formengine-field-item t3js-formengine-field-item"><div class="form-description">'+TYPO3.lang["formManager.form_template_description"]+'</div><div class="form-control-wrap">'+$(m)[0].outerHTML+"</div></div></div>")),r+='<div class="mb-3"><label for="new-form-name"><strong>'+TYPO3.lang["formManager.form_name"]+'</strong></label><div class="formengine-field-item t3js-formengine-field-item"><div class="form-description">'+TYPO3.lang["formManager.form_name_description"]+'</div><div class="form-control-wrap">',a.formName?(r+='<input class="form-control" id="new-form-name" data-identifier="newFormName" value="'+securityUtility.encodeHtml(a.formName)+'" />',setTimeout((function(){MultiStepWizard.unlockNextStep()}),200)):r+='<input class="form-control has-error" id="new-form-name" data-identifier="newFormName" />',r+="</div></div></div>",i&&(r+='<div class="mb-3"><label for="new-form-save-path"><strong>'+TYPO3.lang["formManager.form_save_path"]+'</strong></label><div class="formengine-field-item t3js-formengine-field-item"><div class="form-description">'+TYPO3.lang["formManager.form_save_path_description"]+'</div><div class="form-control-wrap">'+$(i)[0].outerHTML+"</div></div></div>"),r+="</div>",t.html(r),a.savePath&&$(Identifiers.newFormSavePath,o).val(a.savePath),a.templatePath&&$(Identifiers.newFormTemplate,o).val(a.templatePath),s.length>1?$(Identifiers.newFormPrototypeName,o).focus():c.length>1&&$(Identifiers.newFormTemplate,o).focus();const p=function(){$(Identifiers.newFormTemplate,o).on("change",(function(){MultiStepWizard.set("templatePath",$(Identifiers.newFormTemplate+" option:selected",o).val()),MultiStepWizard.set("templatePathName",$(Identifiers.newFormTemplate+" option:selected",o).text()),MultiStepWizard.set("templatePathOnPrev",$(Identifiers.newFormTemplate+" option:selected",o).val())}))};$(Identifiers.newFormPrototypeName,o).on("change",(function(t){MultiStepWizard.set("prototypeName",$(Identifiers.newFormPrototypeName+" option:selected",o).val()),MultiStepWizard.set("prototypeNameName",$(Identifiers.newFormPrototypeName+" option:selected",o).text()),c=e.getTemplatesForPrototype($(t.currentTarget).val()),$(Identifiers.newFormTemplate,o).off().empty();for(let e=0,t=c.length;e<t;++e){const t=new Option(c[e].label,c[e].value);$(Identifiers.newFormTemplate,o).append(t),MultiStepWizard.set("templatePath",c[0].value),MultiStepWizard.set("templatePathName",c[0].label)}p()})),p(),a.prototypeName&&($(Identifiers.newFormPrototypeName,o).val(a.prototypeName),$(Identifiers.newFormPrototypeName,o).trigger("change"),a.templatePathOnPrev&&($(Identifiers.newFormTemplate,o).find(selector`option[value="${a.templatePathOnPrev}"]`).prop("selected",!0),$(Identifiers.newFormTemplate,o).trigger("change"))),$(Identifiers.newFormName,o).focus(),$(Identifiers.newFormName,o).on("keyup paste",(function(e){$(e.currentTarget).val().length>0?($(e.currentTarget).removeClass("has-error"),MultiStepWizard.unlockNextStep(),MultiStepWizard.set("formName",$(e.currentTarget).val()),"code"in e&&"Enter"===e.code&&MultiStepWizard.triggerStepButton("next")):($(e.currentTarget).addClass("has-error"),MultiStepWizard.lockNextStep())})),$(Identifiers.newFormSavePath,o).on("change",(function(){MultiStepWizard.set("savePath",$(Identifiers.newFormSavePath+" option:selected",o).val()),MultiStepWizard.set("savePathName",$(Identifiers.newFormSavePath+" option:selected",o).text())})),"blank"===a.newFormMode||a.templatePathName||MultiStepWizard.set("templatePathName",$(Identifiers.newFormTemplate+" option:selected",o).text()),n.on("click",(async function(){MultiStepWizard.setup.forceSelection=!1,t.html($("<div />",{class:"text-center"}).append(await Icons.getIcon("spinner-circle",Icons.sizes.default,null,null)).prop("outerHTML"))}))})),MultiStepWizard.addSlide("new-form-step-3",TYPO3.lang["formManager.newFormWizard.step3.title"],"",Severity.info,TYPO3.lang["formManager.newFormWizard.step3.progressLabel"],(async function(e,t){const a=await Icons.getIcon("actions-cog",Icons.sizes.small),r=await Icons.getIcon("actions-file-t3d",Icons.sizes.small),i=await Icons.getIcon("actions-tag",Icons.sizes.small),o=await Icons.getIcon("actions-database",Icons.sizes.small),n=MultiStepWizard.setup.$carousel.closest(".modal").find(".modal-footer").find('button[name="next"]');let l='<div class="new-form-modal">';l+='<div class="mb-3"><h5 class="form-section-headline">'+TYPO3.lang["formManager.newFormWizard.step3.check"]+"</h5><p>"+TYPO3.lang["formManager.newFormWizard.step3.message"]+'</p></div><div class="alert alert-notice"><div class="alert-body mt-1">',t.prototypeNameName&&(l+='<div class="row my-1"><div class="col col-sm-6">'+a+" "+TYPO3.lang["formManager.form_prototype"]+'</div><div class="col">'+securityUtility.encodeHtml(t.prototypeNameName)+"</div></div>"),t.templatePathName&&(l+='<div class="row my-1"><div class="col col-sm-6">'+r+" "+TYPO3.lang["formManager.form_template"]+'</div><div class="col">'+securityUtility.encodeHtml(t.templatePathName)+"</div></div>"),l+='<div class="row my-1"><div class="col col-sm-6">'+i+" "+TYPO3.lang["formManager.form_name"]+'</div><div class="col">'+securityUtility.encodeHtml(t.formName)+'</div></div><div class="row my-1"><div class="col col-sm-6">'+o+" "+TYPO3.lang["formManager.form_save_path"]+'</div><div class="col">'+securityUtility.encodeHtml(t.savePathName)+"</div></div>",l+="</div></div></div>",e.html(l),n.focus(),n.on("click",(async function(){MultiStepWizard.setup.forceSelection=!1,e.html($("<div />",{class:"text-center"}).append(await Icons.getIcon("spinner-circle",Icons.sizes.default,null,null)).prop("outerHTML"))}))})),MultiStepWizard.addFinalProcessingSlide((function(){$.post(e.getAjaxEndpoint("create"),{formName:MultiStepWizard.setup.settings.formName,templatePath:MultiStepWizard.setup.settings.templatePath,prototypeName:MultiStepWizard.setup.settings.prototypeName,savePath:MultiStepWizard.setup.settings.savePath},(function(e){"success"===e.status?document.location=e.url:Notification.error(TYPO3.lang["formManager.newFormWizard.step4.errorTitle"],TYPO3.lang["formManager.newFormWizard.step4.errorMessage"]+" "+e.message),MultiStepWizard.dismiss()})).fail((function(e,t,a){const r=(new DOMParser).parseFromString(e.responseText,"text/html"),i=$(r.body);Notification.error(t,a,2),MultiStepWizard.dismiss(),$(Identifiers.t3Logo,i).remove(),$(Identifiers.t3Footer,i).remove(),$(Identifiers.moduleBody).html(i.html())}))})).then((function(){MultiStepWizard.show()}))}))}function removeFormSetup(e){$(Identifiers.removeFormModalTrigger).on("click",(function(t){const a=[];t.preventDefault();const r=$(t.currentTarget);a.push({text:TYPO3.lang["formManager.cancel"],active:!0,btnClass:"btn-default",name:"cancel",trigger:function(e,t){t.hideModal()}}),a.push({text:TYPO3.lang["formManager.remove_form"],active:!0,btnClass:"btn-warning",name:"createform",trigger:function(t,a){document.location=e.getAjaxEndpoint("delete")+"&formPersistenceIdentifier="+r.data("formPersistenceIdentifier"),a.hideModal()}}),Modal.show(TYPO3.lang["formManager.remove_form_title"],TYPO3.lang["formManager.remove_form_message"],Severity.warning,a)}))}function duplicateFormSetup(e){$(Identifiers.duplicateFormModalTrigger).on("click",(function(t){t.preventDefault();const a=$(t.currentTarget);MultiStepWizard.addSlide("duplicate-form-step-1",TYPO3.lang["formManager.duplicateFormWizard.step1.title"].replace("{0}",a.data("formName")),"",Severity.info,top.TYPO3.lang["wizard.progressStep.configure"],(function(t){let r,i;MultiStepWizard.lockPrevStep(),MultiStepWizard.lockNextStep();const o=MultiStepWizard.setup.$carousel.closest(".modal"),n=o.find(".modal-footer").find('button[name="next"]'),l=e.getAccessibleFormStorageFolders();if(e.assert(l.length>0,"No accessible form storage folders",1477649539),MultiStepWizard.set("formPersistenceIdentifier",a.data("formPersistenceIdentifier")),MultiStepWizard.set("savePath",l[0].value),l.length>1){i=$('<select id="duplicate-form-save-path" class="form-select" data-identifier="duplicateFormSavePath" />');for(let e=0,t=l.length;e<t;++e){const t=new Option(l[e].label,l[e].value);$(i).append(t)}}r='<div class="duplicate-form-modal"><h5 class="form-section-headline">'+TYPO3.lang["formManager.new_form_name"]+'</h5><div class="mb-3"><label for="duplicate-form-name"><strong>'+TYPO3.lang["formManager.form_name"]+'</strong></label><div class="formengine-field-item t3js-formengine-field-item"><div class="form-description">'+TYPO3.lang["formManager.form_name_description"]+'</div><div class="form-control-wrap"><input id="duplicate-form-name" class="form-control has-error" data-identifier="duplicateFormName" /></div></div></div>',i&&(r+='<div class="mb-3"><label for="duplicate-form-save-path"><strong>'+TYPO3.lang["formManager.form_save_path"]+'</strong></label><div class="formengine-field-item t3js-formengine-field-item"><div class="form-description">'+TYPO3.lang["formManager.form_save_path_description"]+'</div><div class="form-control-wrap">'+$(i)[0].outerHTML+"</div></div></div>"),r+="</div>",t.html(r),$(Identifiers.duplicateFormName,o).focus(),$(Identifiers.duplicateFormName,o).on("keyup paste",(function(e){const t=$(event.currentTarget);t.val().length>0?(t.removeClass("has-error"),MultiStepWizard.unlockNextStep(),MultiStepWizard.set("formName",t.val()),"code"in e&&"Enter"===e.code&&MultiStepWizard.triggerStepButton("next")):(t.addClass("has-error"),MultiStepWizard.lockNextStep())})),n.on("click",(async function(){MultiStepWizard.setup.forceSelection=!1,MultiStepWizard.set("confirmationDuplicateFormName",a.data("formName")),l.length>1?(MultiStepWizard.set("savePath",$(Identifiers.duplicateFormSavePath+" option:selected",o).val()),MultiStepWizard.set("confirmationDuplicateFormSavePath",$(Identifiers.duplicateFormSavePath+" option:selected",o).text())):(MultiStepWizard.set("savePath",l[0].value),MultiStepWizard.set("confirmationDuplicateFormSavePath",l[0].label)),t.html($("<div />",{class:"text-center"}).append(await Icons.getIcon("spinner-circle",Icons.sizes.default,null,null)).prop("outerHTML"))}))})),MultiStepWizard.addSlide("duplicate-form-step-2",TYPO3.lang["formManager.duplicateFormWizard.step2.title"],"",Severity.info,TYPO3.lang["formManager.duplicateFormWizard.step2.progressLabel"],(async function(e,t){const a=await Icons.getIcon("actions-file-t3d",Icons.sizes.small),r=await Icons.getIcon("actions-tag",Icons.sizes.small),i=await Icons.getIcon("actions-database",Icons.sizes.small);MultiStepWizard.unlockPrevStep(),MultiStepWizard.unlockNextStep();const o=MultiStepWizard.setup.$carousel.closest(".modal").find(".modal-footer").find('button[name="next"]');let n='<div class="new-form-modal"><div class="row"><div class="col">';n+='<div class="mb-3"><h5 class="form-section-headline">'+TYPO3.lang["formManager.duplicateFormWizard.step2.check"]+"</h5><p>"+TYPO3.lang["formManager.newFormWizard.step3.message"]+'</p></div><div class="alert alert-notice"><div class="alert-body mt-1"><div class="dropdown-table-row"><div class="dropdown-table-column dropdown-table-icon">'+a+'</div><div class="dropdown-table-column dropdown-table-title">'+TYPO3.lang["formManager.form_copied"]+'</div><div class="dropdown-table-column dropdown-table-value">'+securityUtility.encodeHtml(t.confirmationDuplicateFormName)+'</div></div><div class="dropdown-table-row"><div class="dropdown-table-column dropdown-table-icon">'+r+'</div><div class="dropdown-table-column dropdown-table-title">'+TYPO3.lang["formManager.form_name"]+'</div><div class="dropdown-table-column dropdown-table-value">'+securityUtility.encodeHtml(t.formName)+'</div></div><div class="dropdown-table-row"><div class="dropdown-table-column dropdown-table-icon">'+i+'</div><div class="dropdown-table-column dropdown-table-title">'+TYPO3.lang["formManager.form_save_path"]+'</div><div class="dropdown-table-column dropdown-table-value">'+securityUtility.encodeHtml(t.confirmationDuplicateFormSavePath)+"</div></div></div></div>",n+="</div></div></div>",e.html(n),o.focus(),o.on("click",(async function(){MultiStepWizard.setup.forceSelection=!1,e.html($("<div />",{class:"text-center"}).append(await Icons.getIcon("spinner-circle",Icons.sizes.default,null,null)).prop("outerHTML"))}))})),MultiStepWizard.addFinalProcessingSlide((function(){$.post(e.getAjaxEndpoint("duplicate"),{formName:MultiStepWizard.setup.settings.formName,formPersistenceIdentifier:MultiStepWizard.setup.settings.formPersistenceIdentifier,savePath:MultiStepWizard.setup.settings.savePath},(function(e){"success"===e.status?document.location=e.url:Notification.error(TYPO3.lang["formManager.duplicateFormWizard.step3.errorTitle"],TYPO3.lang["formManager.duplicateFormWizard.step3.errorMessage"]+" "+e.message),MultiStepWizard.dismiss()})).fail((function(e,t,a){const r=(new DOMParser).parseFromString(e.responseText,"text/html"),i=$(r.body);Notification.error(t,a,2),MultiStepWizard.dismiss(),$(Identifiers.t3Logo,i).remove(),$(Identifiers.t3Footer,i).remove(),$(Identifiers.moduleBody).html(i.html())}))})).then((function(){MultiStepWizard.show()}))}))}function showReferencesSetup(e){$(Identifiers.showReferences).on("click",(t=>{t.preventDefault();const a=$(t.currentTarget),r=e.getAjaxEndpoint("references")+"&formPersistenceIdentifier="+a.data("formPersistenceIdentifier");$.get(r,(function(e){let t;const r=[];r.push({text:TYPO3.lang["formManager.cancel"],active:!0,btnClass:"btn-default",name:"cancel",trigger:function(e,t){t.hideModal()}});if(e.references.length>0){t="<div><h3>"+TYPO3.lang["formManager.references.headline"].replace("{0}",securityUtility.encodeHtml(a.data("formName")))+'</h3></div><div class="table-fit"><table id="forms" class="table table-striped table-sm"><thead><tr><th>'+TYPO3.lang["formManager.page"]+"</th><th>"+TYPO3.lang["formManager.record"]+"</th></tr></thead><tbody>";for(let a=0,r=e.references.length;a<r;++a)t+="<tr><td>"+securityUtility.encodeHtml(e.references[a].recordPageTitle)+"</td><td>"+e.references[a].recordIcon+'<a href="'+securityUtility.encodeHtml(e.references[a].recordEditUrl)+'" data-identifier="referenceLink">'+securityUtility.encodeHtml(e.references[a].recordTitle)+" (uid: "+securityUtility.encodeHtml(e.references[a].recordUid)+")</a></td></tr>";t+="</tbody></table></div>"}else t="<div><h1>"+TYPO3.lang["formManager.references.title"].replace("{0}",securityUtility.encodeHtml(e.formPersistenceIdentifier))+"</h1></div><div>"+TYPO3.lang["formManager.no_references"]+"</div>";t=$(t),$(Identifiers.referenceLink,t).on("click",(function(e){e.preventDefault(),Modal.currentModal.hideModal(),document.location=$(e.currentTarget).prop("href")})),Modal.show(TYPO3.lang["formManager.references.title"],t,Severity.info,r)})).fail((function(e,t,a){0!==e.status&&Notification.error(t,a,2)}))}))}!function(e){e.newFormModalTrigger='[data-identifier="newForm"]',e.duplicateFormModalTrigger='[data-identifier="duplicateForm"]',e.removeFormModalTrigger='[data-identifier="removeForm"]',e.newFormModeButton='[data-identifier="newFormModeButton"]',e.newFormName='[data-identifier="newFormName"]',e.newFormSavePath='[data-identifier="newFormSavePath"]',e.newFormPrototypeName='[data-identifier="newFormPrototypeName"]',e.newFormTemplate='[data-identifier="newFormTemplate"]',e.duplicateFormName='[data-identifier="duplicateFormName"]',e.duplicateFormSavePath='[data-identifier="duplicateFormSavePath"]',e.showReferences='[data-identifier="showReferences"]',e.referenceLink='[data-identifier="referenceLink"]',e.moduleBody=".module-body.t3js-module-body",e.t3Logo=".t3-message-page-logo",e.t3Footer="#t3-footer"}(Identifiers||(Identifiers={}));export function bootstrap(e){removeFormSetup(e),newFormSetup(e),duplicateFormSetup(e),showReferencesSetup(e)} \ No newline at end of file
e95a1224719e[SECURITY] Prevent XSS in FormManager backend module
3 files changed · +8 −6
Build/Sources/TypeScript/form/backend/form-manager/view-model.ts+5 −5 modified@@ -719,7 +719,7 @@ function showReferencesSetup(formManagerApp: FormManager): void { const referencesLength = data.references.length; if (referencesLength > 0) { html = '<div>' - + '<h3>' + TYPO3.lang['formManager.references.headline'].replace('{0}', $that.data('formName')) + '</h3>' + + '<h3>' + TYPO3.lang['formManager.references.headline'].replace('{0}', securityUtility.encodeHtml($that.data('formName'))) + '</h3>' + '</div>' + '<div class="table-fit">' + '<table id="forms" class="table table-striped table-sm">' @@ -733,11 +733,11 @@ function showReferencesSetup(formManagerApp: FormManager): void { for (let i = 0, len = data.references.length; i < len; ++i) { html += '<tr>' - + '<td>' + data.references[i].recordPageTitle + '</td>' + + '<td>' + securityUtility.encodeHtml(data.references[i].recordPageTitle) + '</td>' + '<td>' + data.references[i].recordIcon - + '<a href="' + data.references[i].recordEditUrl + '" data-identifier="referenceLink">' - + data.references[i].recordTitle + ' (uid: ' + data.references[i].recordUid + ')' + + '<a href="' + securityUtility.encodeHtml(data.references[i].recordEditUrl) + '" data-identifier="referenceLink">' + + securityUtility.encodeHtml(data.references[i].recordTitle) + ' (uid: ' + securityUtility.encodeHtml(data.references[i].recordUid) + ')' + '</a>' + '</td>' + '</tr>'; @@ -748,7 +748,7 @@ function showReferencesSetup(formManagerApp: FormManager): void { + '</div>'; } else { html = '<div>' - + '<h1>' + TYPO3.lang['formManager.references.title'].replace('{0}', data.formPersistenceIdentifier) + '</h1>' + + '<h1>' + TYPO3.lang['formManager.references.title'].replace('{0}', securityUtility.encodeHtml(data.formPersistenceIdentifier)) + '</h1>' + '</div>' + '<div>' + TYPO3.lang['formManager.no_references'] + '</div>'; }
typo3/sysext/form/Classes/Controller/FormManagerController.php+2 −0 modified@@ -173,6 +173,7 @@ protected function createAction(string $formName, string $templatePath, string $ 'url' => $this->uriBuilder->uriFor('index', ['formPersistenceIdentifier' => $formPersistenceIdentifier], 'FormEditor'), ]; + $form = ArrayUtility::stripTagsFromValuesRecursive($form); try { $this->formPersistenceManager->save($formPersistenceIdentifier, $form); } catch (PersistenceManagerException $e) { @@ -237,6 +238,7 @@ protected function duplicateAction(string $formName, string $formPersistenceIden 'url' => $this->uriBuilder->uriFor('index', ['formPersistenceIdentifier' => $formPersistenceIdentifier], 'FormEditor'), ]; + $formToDuplicate = ArrayUtility::stripTagsFromValuesRecursive($formToDuplicate); try { $this->formPersistenceManager->save($formPersistenceIdentifier, $formToDuplicate); } catch (PersistenceManagerException $e) {
typo3/sysext/form/Resources/Public/JavaScript/backend/form-manager/view-model.js+1 −1 modified@@ -10,4 +10,4 @@ * * The TYPO3 project - inspiring people to share! */ -import $ from"jquery";import Modal from"@typo3/backend/modal.js";import Severity from"@typo3/backend/severity.js";import MultiStepWizard from"@typo3/backend/multi-step-wizard.js";import Icons from"@typo3/backend/icons.js";import Notification from"@typo3/backend/notification.js";import SecurityUtility from"@typo3/core/security-utility.js";import{selector}from"@typo3/core/literals.js";const securityUtility=new SecurityUtility;var Identifiers;function newFormSetup(e){$(Identifiers.newFormModalTrigger).on("click",(function(t){t.preventDefault(),MultiStepWizard.addSlide("new-form-step-1",TYPO3.lang["formManager.newFormWizard.step1.title"],"",Severity.info,TYPO3.lang["formManager.newFormWizard.step1.progressLabel"],(function(t){Icons.getIcon("actions-plus",Icons.sizes.small).then((function(a){Icons.getIcon("form-page",Icons.sizes.large).then((function(r){Icons.getIcon("apps-pagetree-page-default",Icons.sizes.large).then((function(o){let i;const n=MultiStepWizard.setup.$carousel.closest(".modal"),l=n.find(".modal-footer").find('button[name="next"]');MultiStepWizard.blurCancelStep(),MultiStepWizard.lockNextStep(),MultiStepWizard.lockPrevStep();0===e.getAccessibleFormStorageFolders().length&&(i='<div class="new-form-modal"><div class="row"><label class="col col-form-label">'+TYPO3.lang["formManager.newFormWizard.step1.noStorages"]+"</label></div></div>",t.html(i),e.assert(!1,"No accessible form storage folders",1477506500)),i='<div class="new-form-modal">',i+='<div class="card-container"><div class="card card-size-medium"><div class="card-header"><div class="card-icon">'+o+'</div><div class="card-header-body"><h2 class="card-title">'+TYPO3.lang["formManager.blankForm.label"]+'</h2><span class="card-subtitle">'+TYPO3.lang["formManager.blankForm.subtitle"]+'</span></div></div><div class="card-body"><p class="card-text">'+TYPO3.lang["formManager.blankForm.description"]+'</p></div><div class="card-footer"><button type="button" class="btn btn-success" data-inline="1" value="blank" data-identifier="newFormModeButton">'+a+" "+TYPO3.lang["formManager.blankForm.label"]+'</button></div></div><div class="card card-size-medium"><div class="card-header"><div class="card-icon">'+r+'</div><div class="card-header-body"><h2 class="card-title">'+TYPO3.lang["formManager.predefinedForm.label"]+'</h2><span class="card-subtitle">'+TYPO3.lang["formManager.predefinedForm.subtitle"]+'</span></div></div><div class="card-body"><p class="card-text">'+TYPO3.lang["formManager.predefinedForm.description"]+'</p></div><div class="card-footer"><button type="button" class="btn btn-success" data-inline="1" value="predefined" data-identifier="newFormModeButton">'+a+" "+TYPO3.lang["formManager.predefinedForm.label"]+"</button></div></div>",i+="</div>",t.html(i),$(Identifiers.newFormModeButton,n).on("click",(function(e){MultiStepWizard.set("newFormMode",$(e.currentTarget).val()),MultiStepWizard.unlockNextStep().trigger("click")})),l.on("click",(function(){Icons.getIcon("spinner-circle",Icons.sizes.default,null,null).then((function(e){t.html($("<div />",{class:"text-center"}).append(e).prop("outerHTML"))}))}))}))}))}))})),MultiStepWizard.addSlide("new-form-step-2",TYPO3.lang["formManager.newFormWizard.step2.title"],"",Severity.info,top.TYPO3.lang["wizard.progressStep.configure"],(function(t,a){let r,o;MultiStepWizard.lockNextStep(),MultiStepWizard.unlockPrevStep();const i=MultiStepWizard.setup.$carousel.closest(".modal"),n=i.find(".modal-footer").find('button[name="next"]'),l=e.getAccessibleFormStorageFolders();if(a.savePath||(MultiStepWizard.set("savePath",l[0].value),MultiStepWizard.set("savePathName",l[0].label)),l.length>1){o=$('<select class="new-form-save-path form-select" id="new-form-save-path" data-identifier="newFormSavePath" />');for(let e=0,t=l.length;e<t;++e){const t=new Option(l[e].label,l[e].value);$(o).append(t)}}const s=e.getPrototypes();e.assert(s.length>0,"No prototypes available",1477506501),a.prototypeName||(MultiStepWizard.set("prototypeName",s[0].value),MultiStepWizard.set("prototypeNameName",s[0].label));const d=$('<select class="new-form-prototype-name form-select" id="new-form-prototype-name" data-identifier="newFormPrototypeName" />');for(let e=0,t=s.length;e<t;++e){const t=new Option(s[e].label,s[e].value);$(d).append(t)}let c=e.getTemplatesForPrototype(s[0].value);e.assert(c.length>0,"No templates available",1477506502),a.templatePath||(MultiStepWizard.set("templatePath",c[0].value),MultiStepWizard.set("templatePathName",c[0].label));const m=$('<select class="new-form-template form-select" id="new-form-template" data-identifier="newFormTemplate" />');for(let e=0,t=c.length;e<t;++e){const t=new Option(c[e].label,c[e].value);$(m).append(t)}r='<div class="new-form-modal">',"blank"===a.newFormMode?(r+='<h5 class="form-section-headline">'+TYPO3.lang["formManager.blankForm.label"]+"</h5>",MultiStepWizard.set("templatePath","EXT:form/Resources/Private/Backend/Templates/FormEditor/Yaml/NewForms/BlankForm.yaml"),MultiStepWizard.set("templatePathName",TYPO3.lang["formManager.blankForm.label"])):(r+='<h5 class="form-section-headline">'+TYPO3.lang["formManager.predefinedForm.label"]+"</h5>",s.length>1&&(r+='<div class="mb-3"><label for="new-form-prototype-name"><strong>'+TYPO3.lang["formManager.form_prototype"]+'</strong></label><div class="formengine-field-item t3js-formengine-field-item"><div class="form-control-wrap">'+$(d)[0].outerHTML+"</div></div></div>"),c.length>1&&(r+='<div class="mb-3"><label for="new-form-template"><strong>'+TYPO3.lang["formManager.form_template"]+'</strong></label><div class="formengine-field-item t3js-formengine-field-item"><div class="form-description">'+TYPO3.lang["formManager.form_template_description"]+'</div><div class="form-control-wrap">'+$(m)[0].outerHTML+"</div></div></div>")),r+='<div class="mb-3"><label for="new-form-name"><strong>'+TYPO3.lang["formManager.form_name"]+'</strong></label><div class="formengine-field-item t3js-formengine-field-item"><div class="form-description">'+TYPO3.lang["formManager.form_name_description"]+'</div><div class="form-control-wrap">',a.formName?(r+='<input class="form-control" id="new-form-name" data-identifier="newFormName" value="'+securityUtility.encodeHtml(a.formName)+'" />',setTimeout((function(){MultiStepWizard.unlockNextStep()}),200)):r+='<input class="form-control has-error" id="new-form-name" data-identifier="newFormName" />',r+="</div></div></div>",o&&(r+='<div class="mb-3"><label for="new-form-save-path"><strong>'+TYPO3.lang["formManager.form_save_path"]+'</strong></label><div class="formengine-field-item t3js-formengine-field-item"><div class="form-description">'+TYPO3.lang["formManager.form_save_path_description"]+'</div><div class="form-control-wrap">'+$(o)[0].outerHTML+"</div></div></div>"),r+="</div>",t.html(r),a.savePath&&$(Identifiers.newFormSavePath,i).val(a.savePath),a.templatePath&&$(Identifiers.newFormTemplate,i).val(a.templatePath),s.length>1?$(Identifiers.newFormPrototypeName,i).focus():c.length>1&&$(Identifiers.newFormTemplate,i).focus();const p=function(){$(Identifiers.newFormTemplate,i).on("change",(function(){MultiStepWizard.set("templatePath",$(Identifiers.newFormTemplate+" option:selected",i).val()),MultiStepWizard.set("templatePathName",$(Identifiers.newFormTemplate+" option:selected",i).text()),MultiStepWizard.set("templatePathOnPrev",$(Identifiers.newFormTemplate+" option:selected",i).val())}))};$(Identifiers.newFormPrototypeName,i).on("change",(function(t){MultiStepWizard.set("prototypeName",$(Identifiers.newFormPrototypeName+" option:selected",i).val()),MultiStepWizard.set("prototypeNameName",$(Identifiers.newFormPrototypeName+" option:selected",i).text()),c=e.getTemplatesForPrototype($(t.currentTarget).val()),$(Identifiers.newFormTemplate,i).off().empty();for(let e=0,t=c.length;e<t;++e){const t=new Option(c[e].label,c[e].value);$(Identifiers.newFormTemplate,i).append(t),MultiStepWizard.set("templatePath",c[0].value),MultiStepWizard.set("templatePathName",c[0].label)}p()})),p(),a.prototypeName&&($(Identifiers.newFormPrototypeName,i).val(a.prototypeName),$(Identifiers.newFormPrototypeName,i).trigger("change"),a.templatePathOnPrev&&($(Identifiers.newFormTemplate,i).find(selector`option[value="${a.templatePathOnPrev}"]`).prop("selected",!0),$(Identifiers.newFormTemplate,i).trigger("change"))),$(Identifiers.newFormName,i).focus(),$(Identifiers.newFormName,i).on("keyup paste",(function(e){$(e.currentTarget).val().length>0?($(e.currentTarget).removeClass("has-error"),MultiStepWizard.unlockNextStep(),MultiStepWizard.set("formName",$(e.currentTarget).val()),"code"in e&&"Enter"===e.code&&MultiStepWizard.triggerStepButton("next")):($(e.currentTarget).addClass("has-error"),MultiStepWizard.lockNextStep())})),$(Identifiers.newFormSavePath,i).on("change",(function(){MultiStepWizard.set("savePath",$(Identifiers.newFormSavePath+" option:selected",i).val()),MultiStepWizard.set("savePathName",$(Identifiers.newFormSavePath+" option:selected",i).text())})),"blank"===a.newFormMode||a.templatePathName||MultiStepWizard.set("templatePathName",$(Identifiers.newFormTemplate+" option:selected",i).text()),n.on("click",(function(){MultiStepWizard.setup.forceSelection=!1,Icons.getIcon("spinner-circle",Icons.sizes.default,null,null).then((function(e){t.html($("<div />",{class:"text-center"}).append(e).prop("outerHTML"))}))}))})),MultiStepWizard.addSlide("new-form-step-3",TYPO3.lang["formManager.newFormWizard.step3.title"],"",Severity.info,TYPO3.lang["formManager.newFormWizard.step3.progressLabel"],(function(e,t){Icons.getIcon("actions-cog",Icons.sizes.small).then((function(a){Icons.getIcon("actions-file-t3d",Icons.sizes.small).then((function(r){Icons.getIcon("actions-tag",Icons.sizes.small).then((function(o){Icons.getIcon("actions-database",Icons.sizes.small).then((function(i){const n=MultiStepWizard.setup.$carousel.closest(".modal").find(".modal-footer").find('button[name="next"]');let l='<div class="new-form-modal">';l+='<div class="mb-3"><h5 class="form-section-headline">'+TYPO3.lang["formManager.newFormWizard.step3.check"]+"</h5><p>"+TYPO3.lang["formManager.newFormWizard.step3.message"]+'</p></div><div class="alert alert-notice"><div class="alert-body mt-1">',t.prototypeNameName&&(l+='<div class="row my-1"><div class="col col-sm-6">'+a+" "+TYPO3.lang["formManager.form_prototype"]+'</div><div class="col">'+securityUtility.encodeHtml(t.prototypeNameName)+"</div></div>"),t.templatePathName&&(l+='<div class="row my-1"><div class="col col-sm-6">'+r+" "+TYPO3.lang["formManager.form_template"]+'</div><div class="col">'+securityUtility.encodeHtml(t.templatePathName)+"</div></div>"),l+='<div class="row my-1"><div class="col col-sm-6">'+o+" "+TYPO3.lang["formManager.form_name"]+'</div><div class="col">'+securityUtility.encodeHtml(t.formName)+'</div></div><div class="row my-1"><div class="col col-sm-6">'+i+" "+TYPO3.lang["formManager.form_save_path"]+'</div><div class="col">'+securityUtility.encodeHtml(t.savePathName)+"</div></div>",l+="</div></div></div>",e.html(l),n.focus(),n.on("click",(function(){MultiStepWizard.setup.forceSelection=!1,Icons.getIcon("spinner-circle",Icons.sizes.default,null,null).then((function(t){e.html($("<div />",{class:"text-center"}).append(t).prop("outerHTML"))}))}))}))}))}))}))})),MultiStepWizard.addFinalProcessingSlide((function(){$.post(e.getAjaxEndpoint("create"),{formName:MultiStepWizard.setup.settings.formName,templatePath:MultiStepWizard.setup.settings.templatePath,prototypeName:MultiStepWizard.setup.settings.prototypeName,savePath:MultiStepWizard.setup.settings.savePath},(function(e){"success"===e.status?document.location=e.url:Notification.error(TYPO3.lang["formManager.newFormWizard.step4.errorTitle"],TYPO3.lang["formManager.newFormWizard.step4.errorMessage"]+" "+e.message),MultiStepWizard.dismiss()})).fail((function(e,t,a){const r=(new DOMParser).parseFromString(e.responseText,"text/html"),o=$(r.body);Notification.error(t,a,2),MultiStepWizard.dismiss(),$(Identifiers.t3Logo,o).remove(),$(Identifiers.t3Footer,o).remove(),$(Identifiers.moduleBody).html(o.html())}))})).then((function(){MultiStepWizard.show()}))}))}function removeFormSetup(e){$(Identifiers.removeFormModalTrigger).on("click",(function(t){const a=[];t.preventDefault();const r=$(t.currentTarget);a.push({text:TYPO3.lang["formManager.cancel"],active:!0,btnClass:"btn-default",name:"cancel",trigger:function(e,t){t.hideModal()}}),a.push({text:TYPO3.lang["formManager.remove_form"],active:!0,btnClass:"btn-warning",name:"createform",trigger:function(t,a){document.location=e.getAjaxEndpoint("delete")+"&formPersistenceIdentifier="+r.data("formPersistenceIdentifier"),a.hideModal()}}),Modal.show(TYPO3.lang["formManager.remove_form_title"],TYPO3.lang["formManager.remove_form_message"],Severity.warning,a)}))}function duplicateFormSetup(e){$(Identifiers.duplicateFormModalTrigger).on("click",(function(t){t.preventDefault();const a=$(t.currentTarget);MultiStepWizard.addSlide("duplicate-form-step-1",TYPO3.lang["formManager.duplicateFormWizard.step1.title"].replace("{0}",a.data("formName")),"",Severity.info,top.TYPO3.lang["wizard.progressStep.configure"],(function(t){let r,o;MultiStepWizard.lockPrevStep(),MultiStepWizard.lockNextStep();const i=MultiStepWizard.setup.$carousel.closest(".modal"),n=i.find(".modal-footer").find('button[name="next"]'),l=e.getAccessibleFormStorageFolders();if(e.assert(l.length>0,"No accessible form storage folders",1477649539),MultiStepWizard.set("formPersistenceIdentifier",a.data("formPersistenceIdentifier")),MultiStepWizard.set("savePath",l[0].value),l.length>1){o=$('<select id="duplicate-form-save-path" class="form-select" data-identifier="duplicateFormSavePath" />');for(let e=0,t=l.length;e<t;++e){const t=new Option(l[e].label,l[e].value);$(o).append(t)}}r='<div class="duplicate-form-modal"><h5 class="form-section-headline">'+TYPO3.lang["formManager.new_form_name"]+'</h5><div class="mb-3"><label for="duplicate-form-name"><strong>'+TYPO3.lang["formManager.form_name"]+'</strong></label><div class="formengine-field-item t3js-formengine-field-item"><div class="form-description">'+TYPO3.lang["formManager.form_name_description"]+'</div><div class="form-control-wrap"><input id="duplicate-form-name" class="form-control has-error" data-identifier="duplicateFormName" /></div></div></div>',o&&(r+='<div class="mb-3"><label for="duplicate-form-save-path"><strong>'+TYPO3.lang["formManager.form_save_path"]+'</strong></label><div class="formengine-field-item t3js-formengine-field-item"><div class="form-description">'+TYPO3.lang["formManager.form_save_path_description"]+'</div><div class="form-control-wrap">'+$(o)[0].outerHTML+"</div></div></div>"),r+="</div>",t.html(r),$(Identifiers.duplicateFormName,i).focus(),$(Identifiers.duplicateFormName,i).on("keyup paste",(function(e){const t=$(event.currentTarget);t.val().length>0?(t.removeClass("has-error"),MultiStepWizard.unlockNextStep(),MultiStepWizard.set("formName",t.val()),"code"in e&&"Enter"===e.code&&MultiStepWizard.triggerStepButton("next")):(t.addClass("has-error"),MultiStepWizard.lockNextStep())})),n.on("click",(function(){MultiStepWizard.setup.forceSelection=!1,Icons.getIcon("spinner-circle",Icons.sizes.default,null,null).then((function(e){MultiStepWizard.set("confirmationDuplicateFormName",a.data("formName")),l.length>1?(MultiStepWizard.set("savePath",$(Identifiers.duplicateFormSavePath+" option:selected",i).val()),MultiStepWizard.set("confirmationDuplicateFormSavePath",$(Identifiers.duplicateFormSavePath+" option:selected",i).text())):(MultiStepWizard.set("savePath",l[0].value),MultiStepWizard.set("confirmationDuplicateFormSavePath",l[0].label)),t.html($("<div />",{class:"text-center"}).append(e).prop("outerHTML"))}))}))})),MultiStepWizard.addSlide("duplicate-form-step-2",TYPO3.lang["formManager.duplicateFormWizard.step2.title"],"",Severity.info,TYPO3.lang["formManager.duplicateFormWizard.step2.progressLabel"],(function(e,t){Icons.getIcon("actions-file-t3d",Icons.sizes.small).then((function(a){Icons.getIcon("actions-tag",Icons.sizes.small).then((function(r){Icons.getIcon("actions-database",Icons.sizes.small).then((function(o){MultiStepWizard.unlockPrevStep(),MultiStepWizard.unlockNextStep();const i=MultiStepWizard.setup.$carousel.closest(".modal").find(".modal-footer").find('button[name="next"]');let n='<div class="new-form-modal"><div class="row"><div class="col">';n+='<div class="mb-3"><h5 class="form-section-headline">'+TYPO3.lang["formManager.duplicateFormWizard.step2.check"]+"</h5><p>"+TYPO3.lang["formManager.newFormWizard.step3.message"]+'</p></div><div class="alert alert-notice"><div class="alert-body mt-1"><div class="dropdown-table-row"><div class="dropdown-table-column dropdown-table-icon">'+a+'</div><div class="dropdown-table-column dropdown-table-title">'+TYPO3.lang["formManager.form_copied"]+'</div><div class="dropdown-table-column dropdown-table-value">'+securityUtility.encodeHtml(t.confirmationDuplicateFormName)+'</div></div><div class="dropdown-table-row"><div class="dropdown-table-column dropdown-table-icon">'+r+'</div><div class="dropdown-table-column dropdown-table-title">'+TYPO3.lang["formManager.form_name"]+'</div><div class="dropdown-table-column dropdown-table-value">'+securityUtility.encodeHtml(t.formName)+'</div></div><div class="dropdown-table-row"><div class="dropdown-table-column dropdown-table-icon">'+o+'</div><div class="dropdown-table-column dropdown-table-title">'+TYPO3.lang["formManager.form_save_path"]+'</div><div class="dropdown-table-column dropdown-table-value">'+securityUtility.encodeHtml(t.confirmationDuplicateFormSavePath)+"</div></div></div></div>",n+="</div></div></div>",e.html(n),i.focus(),i.on("click",(function(){MultiStepWizard.setup.forceSelection=!1,Icons.getIcon("spinner-circle",Icons.sizes.default,null,null).then((function(t){e.html($("<div />",{class:"text-center"}).append(t).prop("outerHTML"))}))}))}))}))}))})),MultiStepWizard.addFinalProcessingSlide((function(){$.post(e.getAjaxEndpoint("duplicate"),{formName:MultiStepWizard.setup.settings.formName,formPersistenceIdentifier:MultiStepWizard.setup.settings.formPersistenceIdentifier,savePath:MultiStepWizard.setup.settings.savePath},(function(e){"success"===e.status?document.location=e.url:Notification.error(TYPO3.lang["formManager.duplicateFormWizard.step3.errorTitle"],TYPO3.lang["formManager.duplicateFormWizard.step3.errorMessage"]+" "+e.message),MultiStepWizard.dismiss()})).fail((function(e,t,a){const r=(new DOMParser).parseFromString(e.responseText,"text/html"),o=$(r.body);Notification.error(t,a,2),MultiStepWizard.dismiss(),$(Identifiers.t3Logo,o).remove(),$(Identifiers.t3Footer,o).remove(),$(Identifiers.moduleBody).html(o.html())}))})).then((function(){MultiStepWizard.show()}))}))}function showReferencesSetup(e){$(Identifiers.showReferences).on("click",(t=>{t.preventDefault();const a=$(t.currentTarget),r=e.getAjaxEndpoint("references")+"&formPersistenceIdentifier="+a.data("formPersistenceIdentifier");$.get(r,(function(e){let t;const r=[];r.push({text:TYPO3.lang["formManager.cancel"],active:!0,btnClass:"btn-default",name:"cancel",trigger:function(e,t){t.hideModal()}});if(e.references.length>0){t="<div><h3>"+TYPO3.lang["formManager.references.headline"].replace("{0}",a.data("formName"))+'</h3></div><div class="table-fit"><table id="forms" class="table table-striped table-sm"><thead><tr><th>'+TYPO3.lang["formManager.page"]+"</th><th>"+TYPO3.lang["formManager.record"]+"</th></tr></thead><tbody>";for(let a=0,r=e.references.length;a<r;++a)t+="<tr><td>"+e.references[a].recordPageTitle+"</td><td>"+e.references[a].recordIcon+'<a href="'+e.references[a].recordEditUrl+'" data-identifier="referenceLink">'+e.references[a].recordTitle+" (uid: "+e.references[a].recordUid+")</a></td></tr>";t+="</tbody></table></div>"}else t="<div><h1>"+TYPO3.lang["formManager.references.title"].replace("{0}",e.formPersistenceIdentifier)+"</h1></div><div>"+TYPO3.lang["formManager.no_references"]+"</div>";t=$(t),$(Identifiers.referenceLink,t).on("click",(function(e){e.preventDefault(),Modal.currentModal.hideModal(),document.location=$(e.currentTarget).prop("href")})),Modal.show(TYPO3.lang["formManager.references.title"],t,Severity.info,r)})).fail((function(e,t,a){0!==e.status&&Notification.error(t,a,2)}))}))}!function(e){e.newFormModalTrigger='[data-identifier="newForm"]',e.duplicateFormModalTrigger='[data-identifier="duplicateForm"]',e.removeFormModalTrigger='[data-identifier="removeForm"]',e.newFormModeButton='[data-identifier="newFormModeButton"]',e.newFormName='[data-identifier="newFormName"]',e.newFormSavePath='[data-identifier="newFormSavePath"]',e.newFormPrototypeName='[data-identifier="newFormPrototypeName"]',e.newFormTemplate='[data-identifier="newFormTemplate"]',e.duplicateFormName='[data-identifier="duplicateFormName"]',e.duplicateFormSavePath='[data-identifier="duplicateFormSavePath"]',e.showReferences='[data-identifier="showReferences"]',e.referenceLink='[data-identifier="referenceLink"]',e.moduleBody=".module-body.t3js-module-body",e.t3Logo=".t3-message-page-logo",e.t3Footer="#t3-footer"}(Identifiers||(Identifiers={}));export function bootstrap(e){removeFormSetup(e),newFormSetup(e),duplicateFormSetup(e),showReferencesSetup(e)} \ No newline at end of file +import $ from"jquery";import Modal from"@typo3/backend/modal.js";import Severity from"@typo3/backend/severity.js";import MultiStepWizard from"@typo3/backend/multi-step-wizard.js";import Icons from"@typo3/backend/icons.js";import Notification from"@typo3/backend/notification.js";import SecurityUtility from"@typo3/core/security-utility.js";import{selector}from"@typo3/core/literals.js";const securityUtility=new SecurityUtility;var Identifiers;function newFormSetup(e){$(Identifiers.newFormModalTrigger).on("click",(function(t){t.preventDefault(),MultiStepWizard.addSlide("new-form-step-1",TYPO3.lang["formManager.newFormWizard.step1.title"],"",Severity.info,TYPO3.lang["formManager.newFormWizard.step1.progressLabel"],(function(t){Icons.getIcon("actions-plus",Icons.sizes.small).then((function(a){Icons.getIcon("form-page",Icons.sizes.large).then((function(r){Icons.getIcon("apps-pagetree-page-default",Icons.sizes.large).then((function(i){let o;const n=MultiStepWizard.setup.$carousel.closest(".modal"),l=n.find(".modal-footer").find('button[name="next"]');MultiStepWizard.blurCancelStep(),MultiStepWizard.lockNextStep(),MultiStepWizard.lockPrevStep();0===e.getAccessibleFormStorageFolders().length&&(o='<div class="new-form-modal"><div class="row"><label class="col col-form-label">'+TYPO3.lang["formManager.newFormWizard.step1.noStorages"]+"</label></div></div>",t.html(o),e.assert(!1,"No accessible form storage folders",1477506500)),o='<div class="new-form-modal">',o+='<div class="card-container"><div class="card card-size-medium"><div class="card-header"><div class="card-icon">'+i+'</div><div class="card-header-body"><h2 class="card-title">'+TYPO3.lang["formManager.blankForm.label"]+'</h2><span class="card-subtitle">'+TYPO3.lang["formManager.blankForm.subtitle"]+'</span></div></div><div class="card-body"><p class="card-text">'+TYPO3.lang["formManager.blankForm.description"]+'</p></div><div class="card-footer"><button type="button" class="btn btn-success" data-inline="1" value="blank" data-identifier="newFormModeButton">'+a+" "+TYPO3.lang["formManager.blankForm.label"]+'</button></div></div><div class="card card-size-medium"><div class="card-header"><div class="card-icon">'+r+'</div><div class="card-header-body"><h2 class="card-title">'+TYPO3.lang["formManager.predefinedForm.label"]+'</h2><span class="card-subtitle">'+TYPO3.lang["formManager.predefinedForm.subtitle"]+'</span></div></div><div class="card-body"><p class="card-text">'+TYPO3.lang["formManager.predefinedForm.description"]+'</p></div><div class="card-footer"><button type="button" class="btn btn-success" data-inline="1" value="predefined" data-identifier="newFormModeButton">'+a+" "+TYPO3.lang["formManager.predefinedForm.label"]+"</button></div></div>",o+="</div>",t.html(o),$(Identifiers.newFormModeButton,n).on("click",(function(e){MultiStepWizard.set("newFormMode",$(e.currentTarget).val()),MultiStepWizard.unlockNextStep().trigger("click")})),l.on("click",(function(){Icons.getIcon("spinner-circle",Icons.sizes.default,null,null).then((function(e){t.html($("<div />",{class:"text-center"}).append(e).prop("outerHTML"))}))}))}))}))}))})),MultiStepWizard.addSlide("new-form-step-2",TYPO3.lang["formManager.newFormWizard.step2.title"],"",Severity.info,top.TYPO3.lang["wizard.progressStep.configure"],(function(t,a){let r,i;MultiStepWizard.lockNextStep(),MultiStepWizard.unlockPrevStep();const o=MultiStepWizard.setup.$carousel.closest(".modal"),n=o.find(".modal-footer").find('button[name="next"]'),l=e.getAccessibleFormStorageFolders();if(a.savePath||(MultiStepWizard.set("savePath",l[0].value),MultiStepWizard.set("savePathName",l[0].label)),l.length>1){i=$('<select class="new-form-save-path form-select" id="new-form-save-path" data-identifier="newFormSavePath" />');for(let e=0,t=l.length;e<t;++e){const t=new Option(l[e].label,l[e].value);$(i).append(t)}}const s=e.getPrototypes();e.assert(s.length>0,"No prototypes available",1477506501),a.prototypeName||(MultiStepWizard.set("prototypeName",s[0].value),MultiStepWizard.set("prototypeNameName",s[0].label));const d=$('<select class="new-form-prototype-name form-select" id="new-form-prototype-name" data-identifier="newFormPrototypeName" />');for(let e=0,t=s.length;e<t;++e){const t=new Option(s[e].label,s[e].value);$(d).append(t)}let c=e.getTemplatesForPrototype(s[0].value);e.assert(c.length>0,"No templates available",1477506502),a.templatePath||(MultiStepWizard.set("templatePath",c[0].value),MultiStepWizard.set("templatePathName",c[0].label));const m=$('<select class="new-form-template form-select" id="new-form-template" data-identifier="newFormTemplate" />');for(let e=0,t=c.length;e<t;++e){const t=new Option(c[e].label,c[e].value);$(m).append(t)}r='<div class="new-form-modal">',"blank"===a.newFormMode?(r+='<h5 class="form-section-headline">'+TYPO3.lang["formManager.blankForm.label"]+"</h5>",MultiStepWizard.set("templatePath","EXT:form/Resources/Private/Backend/Templates/FormEditor/Yaml/NewForms/BlankForm.yaml"),MultiStepWizard.set("templatePathName",TYPO3.lang["formManager.blankForm.label"])):(r+='<h5 class="form-section-headline">'+TYPO3.lang["formManager.predefinedForm.label"]+"</h5>",s.length>1&&(r+='<div class="mb-3"><label for="new-form-prototype-name"><strong>'+TYPO3.lang["formManager.form_prototype"]+'</strong></label><div class="formengine-field-item t3js-formengine-field-item"><div class="form-control-wrap">'+$(d)[0].outerHTML+"</div></div></div>"),c.length>1&&(r+='<div class="mb-3"><label for="new-form-template"><strong>'+TYPO3.lang["formManager.form_template"]+'</strong></label><div class="formengine-field-item t3js-formengine-field-item"><div class="form-description">'+TYPO3.lang["formManager.form_template_description"]+'</div><div class="form-control-wrap">'+$(m)[0].outerHTML+"</div></div></div>")),r+='<div class="mb-3"><label for="new-form-name"><strong>'+TYPO3.lang["formManager.form_name"]+'</strong></label><div class="formengine-field-item t3js-formengine-field-item"><div class="form-description">'+TYPO3.lang["formManager.form_name_description"]+'</div><div class="form-control-wrap">',a.formName?(r+='<input class="form-control" id="new-form-name" data-identifier="newFormName" value="'+securityUtility.encodeHtml(a.formName)+'" />',setTimeout((function(){MultiStepWizard.unlockNextStep()}),200)):r+='<input class="form-control has-error" id="new-form-name" data-identifier="newFormName" />',r+="</div></div></div>",i&&(r+='<div class="mb-3"><label for="new-form-save-path"><strong>'+TYPO3.lang["formManager.form_save_path"]+'</strong></label><div class="formengine-field-item t3js-formengine-field-item"><div class="form-description">'+TYPO3.lang["formManager.form_save_path_description"]+'</div><div class="form-control-wrap">'+$(i)[0].outerHTML+"</div></div></div>"),r+="</div>",t.html(r),a.savePath&&$(Identifiers.newFormSavePath,o).val(a.savePath),a.templatePath&&$(Identifiers.newFormTemplate,o).val(a.templatePath),s.length>1?$(Identifiers.newFormPrototypeName,o).focus():c.length>1&&$(Identifiers.newFormTemplate,o).focus();const p=function(){$(Identifiers.newFormTemplate,o).on("change",(function(){MultiStepWizard.set("templatePath",$(Identifiers.newFormTemplate+" option:selected",o).val()),MultiStepWizard.set("templatePathName",$(Identifiers.newFormTemplate+" option:selected",o).text()),MultiStepWizard.set("templatePathOnPrev",$(Identifiers.newFormTemplate+" option:selected",o).val())}))};$(Identifiers.newFormPrototypeName,o).on("change",(function(t){MultiStepWizard.set("prototypeName",$(Identifiers.newFormPrototypeName+" option:selected",o).val()),MultiStepWizard.set("prototypeNameName",$(Identifiers.newFormPrototypeName+" option:selected",o).text()),c=e.getTemplatesForPrototype($(t.currentTarget).val()),$(Identifiers.newFormTemplate,o).off().empty();for(let e=0,t=c.length;e<t;++e){const t=new Option(c[e].label,c[e].value);$(Identifiers.newFormTemplate,o).append(t),MultiStepWizard.set("templatePath",c[0].value),MultiStepWizard.set("templatePathName",c[0].label)}p()})),p(),a.prototypeName&&($(Identifiers.newFormPrototypeName,o).val(a.prototypeName),$(Identifiers.newFormPrototypeName,o).trigger("change"),a.templatePathOnPrev&&($(Identifiers.newFormTemplate,o).find(selector`option[value="${a.templatePathOnPrev}"]`).prop("selected",!0),$(Identifiers.newFormTemplate,o).trigger("change"))),$(Identifiers.newFormName,o).focus(),$(Identifiers.newFormName,o).on("keyup paste",(function(e){$(e.currentTarget).val().length>0?($(e.currentTarget).removeClass("has-error"),MultiStepWizard.unlockNextStep(),MultiStepWizard.set("formName",$(e.currentTarget).val()),"code"in e&&"Enter"===e.code&&MultiStepWizard.triggerStepButton("next")):($(e.currentTarget).addClass("has-error"),MultiStepWizard.lockNextStep())})),$(Identifiers.newFormSavePath,o).on("change",(function(){MultiStepWizard.set("savePath",$(Identifiers.newFormSavePath+" option:selected",o).val()),MultiStepWizard.set("savePathName",$(Identifiers.newFormSavePath+" option:selected",o).text())})),"blank"===a.newFormMode||a.templatePathName||MultiStepWizard.set("templatePathName",$(Identifiers.newFormTemplate+" option:selected",o).text()),n.on("click",(function(){MultiStepWizard.setup.forceSelection=!1,Icons.getIcon("spinner-circle",Icons.sizes.default,null,null).then((function(e){t.html($("<div />",{class:"text-center"}).append(e).prop("outerHTML"))}))}))})),MultiStepWizard.addSlide("new-form-step-3",TYPO3.lang["formManager.newFormWizard.step3.title"],"",Severity.info,TYPO3.lang["formManager.newFormWizard.step3.progressLabel"],(function(e,t){Icons.getIcon("actions-cog",Icons.sizes.small).then((function(a){Icons.getIcon("actions-file-t3d",Icons.sizes.small).then((function(r){Icons.getIcon("actions-tag",Icons.sizes.small).then((function(i){Icons.getIcon("actions-database",Icons.sizes.small).then((function(o){const n=MultiStepWizard.setup.$carousel.closest(".modal").find(".modal-footer").find('button[name="next"]');let l='<div class="new-form-modal">';l+='<div class="mb-3"><h5 class="form-section-headline">'+TYPO3.lang["formManager.newFormWizard.step3.check"]+"</h5><p>"+TYPO3.lang["formManager.newFormWizard.step3.message"]+'</p></div><div class="alert alert-notice"><div class="alert-body mt-1">',t.prototypeNameName&&(l+='<div class="row my-1"><div class="col col-sm-6">'+a+" "+TYPO3.lang["formManager.form_prototype"]+'</div><div class="col">'+securityUtility.encodeHtml(t.prototypeNameName)+"</div></div>"),t.templatePathName&&(l+='<div class="row my-1"><div class="col col-sm-6">'+r+" "+TYPO3.lang["formManager.form_template"]+'</div><div class="col">'+securityUtility.encodeHtml(t.templatePathName)+"</div></div>"),l+='<div class="row my-1"><div class="col col-sm-6">'+i+" "+TYPO3.lang["formManager.form_name"]+'</div><div class="col">'+securityUtility.encodeHtml(t.formName)+'</div></div><div class="row my-1"><div class="col col-sm-6">'+o+" "+TYPO3.lang["formManager.form_save_path"]+'</div><div class="col">'+securityUtility.encodeHtml(t.savePathName)+"</div></div>",l+="</div></div></div>",e.html(l),n.focus(),n.on("click",(function(){MultiStepWizard.setup.forceSelection=!1,Icons.getIcon("spinner-circle",Icons.sizes.default,null,null).then((function(t){e.html($("<div />",{class:"text-center"}).append(t).prop("outerHTML"))}))}))}))}))}))}))})),MultiStepWizard.addFinalProcessingSlide((function(){$.post(e.getAjaxEndpoint("create"),{formName:MultiStepWizard.setup.settings.formName,templatePath:MultiStepWizard.setup.settings.templatePath,prototypeName:MultiStepWizard.setup.settings.prototypeName,savePath:MultiStepWizard.setup.settings.savePath},(function(e){"success"===e.status?document.location=e.url:Notification.error(TYPO3.lang["formManager.newFormWizard.step4.errorTitle"],TYPO3.lang["formManager.newFormWizard.step4.errorMessage"]+" "+e.message),MultiStepWizard.dismiss()})).fail((function(e,t,a){const r=(new DOMParser).parseFromString(e.responseText,"text/html"),i=$(r.body);Notification.error(t,a,2),MultiStepWizard.dismiss(),$(Identifiers.t3Logo,i).remove(),$(Identifiers.t3Footer,i).remove(),$(Identifiers.moduleBody).html(i.html())}))})).then((function(){MultiStepWizard.show()}))}))}function removeFormSetup(e){$(Identifiers.removeFormModalTrigger).on("click",(function(t){const a=[];t.preventDefault();const r=$(t.currentTarget);a.push({text:TYPO3.lang["formManager.cancel"],active:!0,btnClass:"btn-default",name:"cancel",trigger:function(e,t){t.hideModal()}}),a.push({text:TYPO3.lang["formManager.remove_form"],active:!0,btnClass:"btn-warning",name:"createform",trigger:function(t,a){document.location=e.getAjaxEndpoint("delete")+"&formPersistenceIdentifier="+r.data("formPersistenceIdentifier"),a.hideModal()}}),Modal.show(TYPO3.lang["formManager.remove_form_title"],TYPO3.lang["formManager.remove_form_message"],Severity.warning,a)}))}function duplicateFormSetup(e){$(Identifiers.duplicateFormModalTrigger).on("click",(function(t){t.preventDefault();const a=$(t.currentTarget);MultiStepWizard.addSlide("duplicate-form-step-1",TYPO3.lang["formManager.duplicateFormWizard.step1.title"].replace("{0}",a.data("formName")),"",Severity.info,top.TYPO3.lang["wizard.progressStep.configure"],(function(t){let r,i;MultiStepWizard.lockPrevStep(),MultiStepWizard.lockNextStep();const o=MultiStepWizard.setup.$carousel.closest(".modal"),n=o.find(".modal-footer").find('button[name="next"]'),l=e.getAccessibleFormStorageFolders();if(e.assert(l.length>0,"No accessible form storage folders",1477649539),MultiStepWizard.set("formPersistenceIdentifier",a.data("formPersistenceIdentifier")),MultiStepWizard.set("savePath",l[0].value),l.length>1){i=$('<select id="duplicate-form-save-path" class="form-select" data-identifier="duplicateFormSavePath" />');for(let e=0,t=l.length;e<t;++e){const t=new Option(l[e].label,l[e].value);$(i).append(t)}}r='<div class="duplicate-form-modal"><h5 class="form-section-headline">'+TYPO3.lang["formManager.new_form_name"]+'</h5><div class="mb-3"><label for="duplicate-form-name"><strong>'+TYPO3.lang["formManager.form_name"]+'</strong></label><div class="formengine-field-item t3js-formengine-field-item"><div class="form-description">'+TYPO3.lang["formManager.form_name_description"]+'</div><div class="form-control-wrap"><input id="duplicate-form-name" class="form-control has-error" data-identifier="duplicateFormName" /></div></div></div>',i&&(r+='<div class="mb-3"><label for="duplicate-form-save-path"><strong>'+TYPO3.lang["formManager.form_save_path"]+'</strong></label><div class="formengine-field-item t3js-formengine-field-item"><div class="form-description">'+TYPO3.lang["formManager.form_save_path_description"]+'</div><div class="form-control-wrap">'+$(i)[0].outerHTML+"</div></div></div>"),r+="</div>",t.html(r),$(Identifiers.duplicateFormName,o).focus(),$(Identifiers.duplicateFormName,o).on("keyup paste",(function(e){const t=$(event.currentTarget);t.val().length>0?(t.removeClass("has-error"),MultiStepWizard.unlockNextStep(),MultiStepWizard.set("formName",t.val()),"code"in e&&"Enter"===e.code&&MultiStepWizard.triggerStepButton("next")):(t.addClass("has-error"),MultiStepWizard.lockNextStep())})),n.on("click",(function(){MultiStepWizard.setup.forceSelection=!1,Icons.getIcon("spinner-circle",Icons.sizes.default,null,null).then((function(e){MultiStepWizard.set("confirmationDuplicateFormName",a.data("formName")),l.length>1?(MultiStepWizard.set("savePath",$(Identifiers.duplicateFormSavePath+" option:selected",o).val()),MultiStepWizard.set("confirmationDuplicateFormSavePath",$(Identifiers.duplicateFormSavePath+" option:selected",o).text())):(MultiStepWizard.set("savePath",l[0].value),MultiStepWizard.set("confirmationDuplicateFormSavePath",l[0].label)),t.html($("<div />",{class:"text-center"}).append(e).prop("outerHTML"))}))}))})),MultiStepWizard.addSlide("duplicate-form-step-2",TYPO3.lang["formManager.duplicateFormWizard.step2.title"],"",Severity.info,TYPO3.lang["formManager.duplicateFormWizard.step2.progressLabel"],(function(e,t){Icons.getIcon("actions-file-t3d",Icons.sizes.small).then((function(a){Icons.getIcon("actions-tag",Icons.sizes.small).then((function(r){Icons.getIcon("actions-database",Icons.sizes.small).then((function(i){MultiStepWizard.unlockPrevStep(),MultiStepWizard.unlockNextStep();const o=MultiStepWizard.setup.$carousel.closest(".modal").find(".modal-footer").find('button[name="next"]');let n='<div class="new-form-modal"><div class="row"><div class="col">';n+='<div class="mb-3"><h5 class="form-section-headline">'+TYPO3.lang["formManager.duplicateFormWizard.step2.check"]+"</h5><p>"+TYPO3.lang["formManager.newFormWizard.step3.message"]+'</p></div><div class="alert alert-notice"><div class="alert-body mt-1"><div class="dropdown-table-row"><div class="dropdown-table-column dropdown-table-icon">'+a+'</div><div class="dropdown-table-column dropdown-table-title">'+TYPO3.lang["formManager.form_copied"]+'</div><div class="dropdown-table-column dropdown-table-value">'+securityUtility.encodeHtml(t.confirmationDuplicateFormName)+'</div></div><div class="dropdown-table-row"><div class="dropdown-table-column dropdown-table-icon">'+r+'</div><div class="dropdown-table-column dropdown-table-title">'+TYPO3.lang["formManager.form_name"]+'</div><div class="dropdown-table-column dropdown-table-value">'+securityUtility.encodeHtml(t.formName)+'</div></div><div class="dropdown-table-row"><div class="dropdown-table-column dropdown-table-icon">'+i+'</div><div class="dropdown-table-column dropdown-table-title">'+TYPO3.lang["formManager.form_save_path"]+'</div><div class="dropdown-table-column dropdown-table-value">'+securityUtility.encodeHtml(t.confirmationDuplicateFormSavePath)+"</div></div></div></div>",n+="</div></div></div>",e.html(n),o.focus(),o.on("click",(function(){MultiStepWizard.setup.forceSelection=!1,Icons.getIcon("spinner-circle",Icons.sizes.default,null,null).then((function(t){e.html($("<div />",{class:"text-center"}).append(t).prop("outerHTML"))}))}))}))}))}))})),MultiStepWizard.addFinalProcessingSlide((function(){$.post(e.getAjaxEndpoint("duplicate"),{formName:MultiStepWizard.setup.settings.formName,formPersistenceIdentifier:MultiStepWizard.setup.settings.formPersistenceIdentifier,savePath:MultiStepWizard.setup.settings.savePath},(function(e){"success"===e.status?document.location=e.url:Notification.error(TYPO3.lang["formManager.duplicateFormWizard.step3.errorTitle"],TYPO3.lang["formManager.duplicateFormWizard.step3.errorMessage"]+" "+e.message),MultiStepWizard.dismiss()})).fail((function(e,t,a){const r=(new DOMParser).parseFromString(e.responseText,"text/html"),i=$(r.body);Notification.error(t,a,2),MultiStepWizard.dismiss(),$(Identifiers.t3Logo,i).remove(),$(Identifiers.t3Footer,i).remove(),$(Identifiers.moduleBody).html(i.html())}))})).then((function(){MultiStepWizard.show()}))}))}function showReferencesSetup(e){$(Identifiers.showReferences).on("click",(t=>{t.preventDefault();const a=$(t.currentTarget),r=e.getAjaxEndpoint("references")+"&formPersistenceIdentifier="+a.data("formPersistenceIdentifier");$.get(r,(function(e){let t;const r=[];r.push({text:TYPO3.lang["formManager.cancel"],active:!0,btnClass:"btn-default",name:"cancel",trigger:function(e,t){t.hideModal()}});if(e.references.length>0){t="<div><h3>"+TYPO3.lang["formManager.references.headline"].replace("{0}",securityUtility.encodeHtml(a.data("formName")))+'</h3></div><div class="table-fit"><table id="forms" class="table table-striped table-sm"><thead><tr><th>'+TYPO3.lang["formManager.page"]+"</th><th>"+TYPO3.lang["formManager.record"]+"</th></tr></thead><tbody>";for(let a=0,r=e.references.length;a<r;++a)t+="<tr><td>"+securityUtility.encodeHtml(e.references[a].recordPageTitle)+"</td><td>"+e.references[a].recordIcon+'<a href="'+securityUtility.encodeHtml(e.references[a].recordEditUrl)+'" data-identifier="referenceLink">'+securityUtility.encodeHtml(e.references[a].recordTitle)+" (uid: "+securityUtility.encodeHtml(e.references[a].recordUid)+")</a></td></tr>";t+="</tbody></table></div>"}else t="<div><h1>"+TYPO3.lang["formManager.references.title"].replace("{0}",securityUtility.encodeHtml(e.formPersistenceIdentifier))+"</h1></div><div>"+TYPO3.lang["formManager.no_references"]+"</div>";t=$(t),$(Identifiers.referenceLink,t).on("click",(function(e){e.preventDefault(),Modal.currentModal.hideModal(),document.location=$(e.currentTarget).prop("href")})),Modal.show(TYPO3.lang["formManager.references.title"],t,Severity.info,r)})).fail((function(e,t,a){0!==e.status&&Notification.error(t,a,2)}))}))}!function(e){e.newFormModalTrigger='[data-identifier="newForm"]',e.duplicateFormModalTrigger='[data-identifier="duplicateForm"]',e.removeFormModalTrigger='[data-identifier="removeForm"]',e.newFormModeButton='[data-identifier="newFormModeButton"]',e.newFormName='[data-identifier="newFormName"]',e.newFormSavePath='[data-identifier="newFormSavePath"]',e.newFormPrototypeName='[data-identifier="newFormPrototypeName"]',e.newFormTemplate='[data-identifier="newFormTemplate"]',e.duplicateFormName='[data-identifier="duplicateFormName"]',e.duplicateFormSavePath='[data-identifier="duplicateFormSavePath"]',e.showReferences='[data-identifier="showReferences"]',e.referenceLink='[data-identifier="referenceLink"]',e.moduleBody=".module-body.t3js-module-body",e.t3Logo=".t3-message-page-logo",e.t3Footer="#t3-footer"}(Identifiers||(Identifiers={}));export function bootstrap(e){removeFormSetup(e),newFormSetup(e),duplicateFormSetup(e),showReferencesSetup(e)} \ No newline at end of file
d0393a879a32[SECURITY] Prevent XSS in FormManager backend module
2 files changed · +7 −5
typo3/sysext/form/Classes/Controller/FormManagerController.php+2 −0 modified@@ -176,6 +176,7 @@ public function createAction(string $formName, string $templatePath, string $pro 'url' => $this->uriBuilder->uriFor('index', ['formPersistenceIdentifier' => $formPersistenceIdentifier], 'FormEditor'), ]; + $form = ArrayUtility::stripTagsFromValuesRecursive($form); try { $this->formPersistenceManager->save($formPersistenceIdentifier, $form); } catch (PersistenceManagerException $e) { @@ -247,6 +248,7 @@ public function duplicateAction(string $formName, string $formPersistenceIdentif 'url' => $this->uriBuilder->uriFor('index', ['formPersistenceIdentifier' => $formPersistenceIdentifier], 'FormEditor'), ]; + $formToDuplicate = ArrayUtility::stripTagsFromValuesRecursive($formToDuplicate); try { $this->formPersistenceManager->save($formPersistenceIdentifier, $formToDuplicate); } catch (PersistenceManagerException $e) {
typo3/sysext/form/Resources/Public/JavaScript/Backend/FormManager/ViewModel.js+5 −5 modified@@ -768,7 +768,7 @@ define(['jquery', referencesLength = data['references'].length; if (referencesLength > 0) { html = '<div>' - + '<h3>' + TYPO3.lang['formManager.references.headline'].replace('{0}', $(that).data('formName')) + '</h3>' + + '<h3>' + TYPO3.lang['formManager.references.headline'].replace('{0}', securityUtility.encodeHtml($(that).data('formName'))) + '</h3>' + '</div>' + '<div class="table-fit">' + '<table id="forms" class="table table-striped table-sm">' @@ -782,11 +782,11 @@ define(['jquery', for (var i = 0, len = data['references'].length; i < len; ++i) { html += '<tr>' - + '<td>' + data['references'][i]['recordPageTitle'] + '</td>' + + '<td>' + securityUtility.encodeHtml(data['references'][i]['recordPageTitle']) + '</td>' + '<td>' + data['references'][i]['recordIcon'] - + '<a href="' + data['references'][i]['recordEditUrl'] + '" data-identifier="referenceLink">' - + data['references'][i]['recordTitle'] + ' (uid: ' + data['references'][i]['recordUid'] + ')' + + '<a href="' + securityUtility.encodeHtml(data['references'][i]['recordEditUrl']) + '" data-identifier="referenceLink">' + + securityUtility.encodeHtml(data['references'][i]['recordTitle']) + ' (uid: ' + securityUtility.encodeHtml(data['references'][i]['recordUid']) + ')' + '</a>' + '</td>' + '</tr>'; @@ -797,7 +797,7 @@ define(['jquery', + '</div>'; } else { html = '<div>' - + '<h1>' + TYPO3.lang['formManager.references.title'].replace('{0}', data['formPersistenceIdentifier']) + '</h1>' + + '<h1>' + TYPO3.lang['formManager.references.title'].replace('{0}', securityUtility.encodeHtml(data['formPersistenceIdentifier'])) + '</h1>' + '</div>' + '<div>' + TYPO3.lang['formManager.no_references'] + '</div>'; }
Vulnerability mechanics
Generated on May 9, 2026. Inputs: CWE entries + fix-commit diffs from this CVE's patches. Citations validated against bundle.
References
7- github.com/advisories/GHSA-v6mw-h7w6-59w3ghsaADVISORY
- nvd.nist.gov/vuln/detail/CVE-2024-34356ghsaADVISORY
- github.com/TYPO3/typo3/commit/2832e2f51f929aeddb5de7d667538a33ceda8156ghsax_refsource_MISCWEB
- github.com/TYPO3/typo3/commit/d0393a879a32fb4e3569acad6bdb5cda776be1e5ghsax_refsource_MISCWEB
- github.com/TYPO3/typo3/commit/e95a1224719efafb9cab2d85964f240fd0356e64ghsax_refsource_MISCWEB
- github.com/TYPO3/typo3/security/advisories/GHSA-v6mw-h7w6-59w3ghsax_refsource_CONFIRMWEB
- typo3.org/security/advisory/typo3-core-sa-2024-008ghsax_refsource_MISCWEB
News mentions
0No linked articles in our index yet.