typo3-typescript-sources 13.4.20
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/.github/workflows/sync-and-publish.yml +265 -0
- package/.last-synced-tag +1 -0
- package/LICENSE.txt +339 -0
- package/README-TYPO3.md +166 -0
- package/README.md +28 -0
- package/adminpanel/admin-panel.ts +375 -0
- package/adminpanel/modules/cache.ts +27 -0
- package/adminpanel/modules/preview.ts +75 -0
- package/backend/action-button/abstract-action.ts +22 -0
- package/backend/action-button/deferred-action.ts +41 -0
- package/backend/action-button/immediate-action.ts +31 -0
- package/backend/action-dispatcher.ts +104 -0
- package/backend/ajax-data-handler/message-interface.ts +18 -0
- package/backend/ajax-data-handler/response-interface.ts +20 -0
- package/backend/ajax-data-handler.ts +214 -0
- package/backend/backend-exception.ts +22 -0
- package/backend/broadcast-message.ts +50 -0
- package/backend/broadcast-service.ts +52 -0
- package/backend/browse-database.ts +38 -0
- package/backend/clear-cache.ts +88 -0
- package/backend/clipboard-panel.ts +240 -0
- package/backend/close-current-window.ts +2 -0
- package/backend/code-editor/autocomplete/completion-result.ts +105 -0
- package/backend/code-editor/autocomplete/ts-code-completion.ts +142 -0
- package/backend/code-editor/autocomplete/ts-parser.ts +485 -0
- package/backend/code-editor/autocomplete/ts-ref.ts +164 -0
- package/backend/code-editor/element/code-mirror-element.ts +282 -0
- package/backend/code-editor/language/typoscript.ts +181 -0
- package/backend/code-editor/stream-parser/typoscript.ts +1600 -0
- package/backend/color-picker.ts +158 -0
- package/backend/color-scheme-switch.ts +179 -0
- package/backend/column-selector-button.ts +302 -0
- package/backend/context-help.ts +68 -0
- package/backend/context-menu-actions.ts +322 -0
- package/backend/context-menu.ts +751 -0
- package/backend/copy-to-clipboard.ts +79 -0
- package/backend/date-time-picker.ts +270 -0
- package/backend/document-save-actions.ts +159 -0
- package/backend/drag-tooltip.ts +285 -0
- package/backend/drag-uploader.ts +914 -0
- package/backend/element/alert-element.ts +116 -0
- package/backend/element/dispatch-modal-button.ts +50 -0
- package/backend/element/draggable-resizable-element.ts +249 -0
- package/backend/element/editable-page-title.ts +306 -0
- package/backend/element/icon-element.ts +84 -0
- package/backend/element/immediate-action-element.ts +89 -0
- package/backend/element/pagination.ts +59 -0
- package/backend/element/progress-bar-element.ts +172 -0
- package/backend/element/progress-tracker-element.ts +119 -0
- package/backend/element/pseudo-button.ts +58 -0
- package/backend/element/spinner-element.ts +51 -0
- package/backend/element/thumbnail-element.ts +80 -0
- package/backend/element-browser.ts +182 -0
- package/backend/enum/data-transfer-types.ts +21 -0
- package/backend/enum/icon-types.ts +31 -0
- package/backend/enum/key-types.ts +27 -0
- package/backend/enum/severity.ts +20 -0
- package/backend/enum/viewport/scaffold-identifier.ts +24 -0
- package/backend/event/client-request.ts +25 -0
- package/backend/event/consumable.ts +18 -0
- package/backend/event/consumer-scope.ts +54 -0
- package/backend/event/event-dispatcher.ts +26 -0
- package/backend/event/interaction-request-assignment.ts +24 -0
- package/backend/event/interaction-request-map.ts +75 -0
- package/backend/event/interaction-request.ts +48 -0
- package/backend/event/trigger-request.ts +56 -0
- package/backend/form/submit-interceptor.ts +66 -0
- package/backend/form-engine/container/files-control-container.ts +716 -0
- package/backend/form-engine/container/flex-form-container-container.ts +166 -0
- package/backend/form-engine/container/flex-form-section-container.ts +210 -0
- package/backend/form-engine/container/inline-control-container.ts +1230 -0
- package/backend/form-engine/container/site-language-container.ts +616 -0
- package/backend/form-engine/element/abstract-sortable-select-items.ts +186 -0
- package/backend/form-engine/element/category-element.ts +160 -0
- package/backend/form-engine/element/color-element.ts +81 -0
- package/backend/form-engine/element/datetime-element.ts +66 -0
- package/backend/form-engine/element/extra/char-counter.ts +112 -0
- package/backend/form-engine/element/extra/select-box-filter.ts +85 -0
- package/backend/form-engine/element/folder-element.ts +66 -0
- package/backend/form-engine/element/group-element.ts +47 -0
- package/backend/form-engine/element/json-element.ts +52 -0
- package/backend/form-engine/element/link-element.ts +121 -0
- package/backend/form-engine/element/mfa-info-element.ts +169 -0
- package/backend/form-engine/element/modifier/resizable.ts +27 -0
- package/backend/form-engine/element/modifier/tabbable.ts +29 -0
- package/backend/form-engine/element/online-media-form-element.ts +65 -0
- package/backend/form-engine/element/password-element.ts +71 -0
- package/backend/form-engine/element/select-multiple-side-by-side-element.ts +83 -0
- package/backend/form-engine/element/select-single-element.ts +82 -0
- package/backend/form-engine/element/select-tree-element.ts +148 -0
- package/backend/form-engine/element/select-tree-toolbar.ts +118 -0
- package/backend/form-engine/element/select-tree.ts +210 -0
- package/backend/form-engine/element/slug-element.ts +243 -0
- package/backend/form-engine/element/suggest/result-container.ts +118 -0
- package/backend/form-engine/element/suggest/result-item.ts +90 -0
- package/backend/form-engine/element/table-permission-element.ts +101 -0
- package/backend/form-engine/element/table-wizard-element.ts +427 -0
- package/backend/form-engine/element/text-element.ts +52 -0
- package/backend/form-engine/element/text-table-element.ts +31 -0
- package/backend/form-engine/field-control/add-record.ts +40 -0
- package/backend/form-engine/field-control/edit-popup.ts +64 -0
- package/backend/form-engine/field-control/insert-clipboard.ts +50 -0
- package/backend/form-engine/field-control/link-popup.ts +53 -0
- package/backend/form-engine/field-control/list-module.ts +40 -0
- package/backend/form-engine/field-control/password-generator.ts +102 -0
- package/backend/form-engine/field-control/reset-selection.ts +48 -0
- package/backend/form-engine/field-wizard/localization-state-selector.ts +67 -0
- package/backend/form-engine/field-wizard/value-picker.ts +123 -0
- package/backend/form-engine/field-wizard/value-slider.ts +86 -0
- package/backend/form-engine/inline-relation/ajax-dispatcher.ts +124 -0
- package/backend/form-engine/inline-relation/inline-response-interface.ts +41 -0
- package/backend/form-engine-link-browser-adapter.ts +129 -0
- package/backend/form-engine-review.ts +155 -0
- package/backend/form-engine-suggest.ts +133 -0
- package/backend/form-engine-validation.ts +686 -0
- package/backend/form-engine.ts +1391 -0
- package/backend/global-event-handler.ts +252 -0
- package/backend/grid-editor.ts +1077 -0
- package/backend/hashing/md5.ts +252 -0
- package/backend/helper.ts +24 -0
- package/backend/hotkeys/hotkey-storage.ts +63 -0
- package/backend/hotkeys.ts +216 -0
- package/backend/icons.ts +236 -0
- package/backend/image-manipulation.ts +885 -0
- package/backend/info-window.ts +46 -0
- package/backend/input/clearable.ts +128 -0
- package/backend/input/index.d.ts +8 -0
- package/backend/java-script-module-import-event-handler.ts +19 -0
- package/backend/key-bindings.ts +42 -0
- package/backend/layout-module/drag-drop.ts +359 -0
- package/backend/layout-module/paste.ts +165 -0
- package/backend/link-browser.ts +89 -0
- package/backend/live-search/element/backend-search.ts +34 -0
- package/backend/live-search/element/hint.ts +33 -0
- package/backend/live-search/element/provider/default-result-item.ts +52 -0
- package/backend/live-search/element/provider/page-provider-result-item.ts +52 -0
- package/backend/live-search/element/result/item/action/action-container.ts +135 -0
- package/backend/live-search/element/result/item/action/action.ts +56 -0
- package/backend/live-search/element/result/item/item-container.ts +224 -0
- package/backend/live-search/element/result/item/item.ts +74 -0
- package/backend/live-search/element/result/result-container.ts +110 -0
- package/backend/live-search/element/result/result-detail-container.ts +50 -0
- package/backend/live-search/element/result/result-pagination.ts +122 -0
- package/backend/live-search/element/search-option-item.ts +70 -0
- package/backend/live-search/live-search-configurator.ts +54 -0
- package/backend/live-search/live-search-shortcut.ts +29 -0
- package/backend/live-search/result-types/backend-module-result-type.ts +8 -0
- package/backend/live-search/result-types/default-result-type.ts +21 -0
- package/backend/live-search/result-types/page-result-type.ts +23 -0
- package/backend/localization.ts +390 -0
- package/backend/login-refresh.ts +525 -0
- package/backend/login.ts +179 -0
- package/backend/mail-link-handler.ts +45 -0
- package/backend/modal-interface.ts +19 -0
- package/backend/modal.ts +685 -0
- package/backend/module/iframe.ts +125 -0
- package/backend/module/router.ts +275 -0
- package/backend/module-menu.ts +550 -0
- package/backend/module.ts +133 -0
- package/backend/multi-record-selection-action.ts +44 -0
- package/backend/multi-record-selection-delete-action.ts +108 -0
- package/backend/multi-record-selection-edit-action.ts +56 -0
- package/backend/multi-record-selection.ts +468 -0
- package/backend/multi-step-wizard.ts +568 -0
- package/backend/new-content-element-wizard-button.ts +51 -0
- package/backend/new-multiple-pages.ts +108 -0
- package/backend/new-record-wizard.ts +680 -0
- package/backend/notification.ts +366 -0
- package/backend/offset.ts +40 -0
- package/backend/online-media.ts +110 -0
- package/backend/page-actions.ts +91 -0
- package/backend/page-link-handler.ts +51 -0
- package/backend/pagetsconfig/pagetsconfig-includes.ts +77 -0
- package/backend/popover.ts +165 -0
- package/backend/record-download-button.ts +104 -0
- package/backend/record-link-handler.ts +31 -0
- package/backend/record-search.ts +44 -0
- package/backend/recordlist.ts +230 -0
- package/backend/resource/resource.ts +35 -0
- package/backend/security/element/csp-reports.ts +406 -0
- package/backend/security/element/sudo-mode.ts +249 -0
- package/backend/security/sudo-mode-interceptor.ts +19 -0
- package/backend/settings/editor/editable-setting.ts +231 -0
- package/backend/settings/editor.ts +451 -0
- package/backend/settings/enum/settings-mode.enum.ts +24 -0
- package/backend/settings/type/base.ts +200 -0
- package/backend/settings/type/bool.ts +56 -0
- package/backend/settings/type/color.ts +64 -0
- package/backend/settings/type/int.ts +85 -0
- package/backend/settings/type/number.ts +61 -0
- package/backend/settings/type/page.ts +100 -0
- package/backend/settings/type/string.ts +77 -0
- package/backend/settings/type/stringlist.ts +87 -0
- package/backend/severity.ts +88 -0
- package/backend/site-inline-actions.ts +32 -0
- package/backend/sortable-table.ts +208 -0
- package/backend/storage/abstract-client-storage.ts +76 -0
- package/backend/storage/browser-session.ts +28 -0
- package/backend/storage/client.ts +28 -0
- package/backend/storage/module-state-storage.ts +118 -0
- package/backend/storage/persistent.ts +204 -0
- package/backend/switch-user.ts +82 -0
- package/backend/tabs.ts +72 -0
- package/backend/telephone-link-handler.ts +40 -0
- package/backend/tests/backend/storage/browser-storage-test.ts +87 -0
- package/backend/tests/backend/storage/client-test.ts +87 -0
- package/backend/tests/backend/utility/dom-helper-test.ts +51 -0
- package/backend/tests/backend-exception-test.ts +28 -0
- package/backend/tests/element/immediate-action-element-test.ts +81 -0
- package/backend/tests/form-engine-validation-test.ts +304 -0
- package/backend/tests/grid-editor-test.ts +29 -0
- package/backend/tests/hashing/md5Test.ts +28 -0
- package/backend/tests/icons-test.ts +23 -0
- package/backend/tests/notification-test.ts +161 -0
- package/backend/tests/popover-test.ts +83 -0
- package/backend/toolbar/clear-cache-menu.ts +88 -0
- package/backend/toolbar/live-search.ts +284 -0
- package/backend/toolbar/shortcut-menu.ts +254 -0
- package/backend/toolbar/system-information-menu.ts +161 -0
- package/backend/toolbar.ts +41 -0
- package/backend/tree/file-storage-browser.ts +194 -0
- package/backend/tree/file-storage-tree-container.ts +465 -0
- package/backend/tree/file-storage-tree.ts +42 -0
- package/backend/tree/page-browser.ts +272 -0
- package/backend/tree/page-tree-element.ts +602 -0
- package/backend/tree/page-tree.ts +152 -0
- package/backend/tree/tree-module-state.ts +159 -0
- package/backend/tree/tree-node-toggle.ts +31 -0
- package/backend/tree/tree-node.ts +97 -0
- package/backend/tree/tree-toolbar.ts +117 -0
- package/backend/tree/tree.ts +1595 -0
- package/backend/url-link-handler.ts +36 -0
- package/backend/user-pass-login.ts +255 -0
- package/backend/user-settings-manager.ts +189 -0
- package/backend/utility/collapse-state-persister.ts +205 -0
- package/backend/utility/collapse-state-search.ts +183 -0
- package/backend/utility/dom-helper.ts +91 -0
- package/backend/utility/drag-drop-utility.ts +47 -0
- package/backend/utility/message-utility.ts +45 -0
- package/backend/utility/top-level-module-import.ts +32 -0
- package/backend/utility.ts +194 -0
- package/backend/viewport/abstract-container.ts +22 -0
- package/backend/viewport/content-container.ts +98 -0
- package/backend/viewport/loader.ts +28 -0
- package/backend/viewport/navigation-container.ts +119 -0
- package/backend/viewport/resizable-navigation.ts +176 -0
- package/backend/viewport/toolbar.ts +27 -0
- package/backend/viewport/topbar.ts +39 -0
- package/backend/viewport.ts +46 -0
- package/backend/window-manager.ts +84 -0
- package/backend/wizard/move-content-element.ts +107 -0
- package/backend/wizard/move-page.ts +74 -0
- package/backend/wizard.ts +331 -0
- package/belog/backend-log.ts +88 -0
- package/beuser/backend-user-listing.ts +40 -0
- package/beuser/permissions.ts +291 -0
- package/core/ajax/ajax-request-types.ts +15 -0
- package/core/ajax/ajax-request.ts +202 -0
- package/core/ajax/ajax-response.ts +57 -0
- package/core/ajax/input-transformer.ts +92 -0
- package/core/ajax/simple-response-interface.ts +5 -0
- package/core/authentication/mfa-provider/totp.ts +54 -0
- package/core/cache/dedupe-async-task.ts +95 -0
- package/core/directive/markdown.ts +82 -0
- package/core/directive/nl2br.ts +16 -0
- package/core/document-service.ts +35 -0
- package/core/event/debounce-event.ts +40 -0
- package/core/event/event-interface.ts +24 -0
- package/core/event/regular-event.ts +58 -0
- package/core/event/request-animation-frame-event.ts +42 -0
- package/core/event/throttle-event.ts +54 -0
- package/core/java-script-item-handler.ts +29 -0
- package/core/java-script-item-processor.ts +171 -0
- package/core/lit-helper.ts +126 -0
- package/core/literals.ts +17 -0
- package/core/referrer-refresh.ts +2 -0
- package/core/security-utility.ts +89 -0
- package/core/tests/ajax/ajax-request-test.ts +290 -0
- package/core/tests/ajax/input-transformer-test.ts +64 -0
- package/core/tests/cache/dedupe-async-task-test.ts +152 -0
- package/core/tests/event/throttle-event-test.ts +47 -0
- package/core/tests/literals-test.ts +24 -0
- package/core/tests/security-utility-test.ts +50 -0
- package/core/utility/types.ts +9 -0
- package/dashboard/chart-initializer.ts +136 -0
- package/dashboard/dashboard.ts +1487 -0
- package/extensionmanager/distribution-image.ts +55 -0
- package/extensionmanager/main.ts +291 -0
- package/extensionmanager/repository.ts +195 -0
- package/extensionmanager/update.ts +118 -0
- package/extensionmanager/upload-form.ts +42 -0
- package/filelist/browse-files.ts +148 -0
- package/filelist/browse-folders.ts +94 -0
- package/filelist/context-menu-actions.ts +335 -0
- package/filelist/create-folder.ts +69 -0
- package/filelist/file-delete.ts +69 -0
- package/filelist/file-list-actions.ts +132 -0
- package/filelist/file-list-dragdrop.ts +139 -0
- package/filelist/file-list-rename-handler.ts +128 -0
- package/filelist/file-list-transfer-handler.ts +138 -0
- package/filelist/file-list.ts +396 -0
- package/filelist/file-replace.ts +37 -0
- package/filelist/linkbrowser-file-handler.ts +94 -0
- package/filelist/linkbrowser-folder-handler.ts +74 -0
- package/filelist/rename-file.ts +109 -0
- package/form/backend/form-editor/component/property-grid-editor.ts +340 -0
- package/form/backend/form-editor/core.ts +2104 -0
- package/form/backend/form-editor/helper.ts +226 -0
- package/form/backend/form-editor/inspector-component.ts +2323 -0
- package/form/backend/form-editor/mediator.ts +941 -0
- package/form/backend/form-editor/modals-component.ts +433 -0
- package/form/backend/form-editor/stage-component.ts +908 -0
- package/form/backend/form-editor/tree-component.ts +548 -0
- package/form/backend/form-editor/view-model.ts +1343 -0
- package/form/backend/form-editor.ts +846 -0
- package/form/backend/form-manager/main.ts +39 -0
- package/form/backend/form-manager/view-model.ts +789 -0
- package/form/backend/form-manager.ts +180 -0
- package/form/backend/helper.ts +60 -0
- package/form/frontend/date-picker.ts +38 -0
- package/frontend/default_frontend.ts +82 -0
- package/impexp/context-menu-actions.ts +50 -0
- package/impexp/import-export.ts +62 -0
- package/indexed-search/pagination.ts +26 -0
- package/indexed-search/statistics.ts +50 -0
- package/info/translation-status.ts +48 -0
- package/install/ajax/ajax-queue.ts +83 -0
- package/install/init-install.ts +2 -0
- package/install/init-installer.ts +2 -0
- package/install/install.ts +25 -0
- package/install/installer.ts +458 -0
- package/install/message-interface.ts +18 -0
- package/install/module/abstract-inline-module.ts +27 -0
- package/install/module/abstract-interactable-module.ts +107 -0
- package/install/module/environment/environment-check.ts +92 -0
- package/install/module/environment/folder-structure.ts +145 -0
- package/install/module/environment/image-processing.ts +141 -0
- package/install/module/environment/mail-test.ts +127 -0
- package/install/module/environment/php-info.ts +50 -0
- package/install/module/environment/system-information.ts +50 -0
- package/install/module/maintenance/cache.ts +59 -0
- package/install/module/maintenance/clear-tables.ts +134 -0
- package/install/module/maintenance/clear-typo3temp-files.ts +137 -0
- package/install/module/maintenance/create-admin.ts +126 -0
- package/install/module/maintenance/database-analyzer.ts +266 -0
- package/install/module/maintenance/dump-autoload.ts +58 -0
- package/install/module/maintenance/language-packs.ts +338 -0
- package/install/module/maintenance/reset-backend-user-uc.ts +58 -0
- package/install/module/password-strength.ts +56 -0
- package/install/module/settings/change-install-tool-password.ts +101 -0
- package/install/module/settings/extension-configuration.ts +224 -0
- package/install/module/settings/features.ts +102 -0
- package/install/module/settings/local-configuration.ts +316 -0
- package/install/module/settings/presets.ts +147 -0
- package/install/module/settings/system-maintainer.ts +111 -0
- package/install/module/upgrade/core-update.ts +255 -0
- package/install/module/upgrade/extension-compat-tester.ts +195 -0
- package/install/module/upgrade/extension-scanner.ts +381 -0
- package/install/module/upgrade/tca-ext-tables-check.ts +93 -0
- package/install/module/upgrade/tca-migrations-check.ts +101 -0
- package/install/module/upgrade/upgrade-docs.ts +310 -0
- package/install/module/upgrade/upgrade-wizards.ts +612 -0
- package/install/renderable/clearable.ts +113 -0
- package/install/renderable/flash-message.ts +64 -0
- package/install/renderable/info-box.ts +66 -0
- package/install/renderable/language-packs.ts +304 -0
- package/install/renderable/offset-group.ts +38 -0
- package/install/renderable/severity.ts +49 -0
- package/install/renderable/wrap-group.ts +36 -0
- package/install/router.ts +468 -0
- package/linkvalidator/linkvalidator-modal.ts +45 -0
- package/linkvalidator/linkvalidator.ts +101 -0
- package/lowlevel/query-generator.ts +132 -0
- package/lowlevel/reference-index.ts +44 -0
- package/opendocs/toolbar/opendocs-menu.ts +117 -0
- package/package.json +34 -0
- package/recycler/recycler.ts +539 -0
- package/redirects/event-handler.ts +108 -0
- package/redirects/form-engine-evaluation.ts +34 -0
- package/redirects/redirects-module.ts +58 -0
- package/rte-ckeditor/ckeditor5.ts +402 -0
- package/rte-ckeditor/css-prefixer.ts +94 -0
- package/rte-ckeditor/legacy/ckeditor5-bundle.ts +17 -0
- package/rte-ckeditor/legacy/ckeditor5-inspector.ts +2 -0
- package/rte-ckeditor/plugin/typo3-link.ts +810 -0
- package/rte-ckeditor/plugin/whitespace.ts +114 -0
- package/rte-ckeditor/rte-link-browser.ts +112 -0
- package/rte-ckeditor/tests/css-prefixer-test.ts +314 -0
- package/scheduler/scheduler-add-group.ts +119 -0
- package/scheduler/scheduler-editable-group-name.ts +307 -0
- package/scheduler/scheduler-sortable-groups.ts +59 -0
- package/scheduler/scheduler.ts +466 -0
- package/setup/setup-module.ts +122 -0
- package/styleguide/checkbox-demo.ts +5 -0
- package/styleguide/element/theme-switcher-element.ts +101 -0
- package/styleguide/filter.ts +22 -0
- package/styleguide/find-icons.ts +78 -0
- package/styleguide/processing-indicator.ts +78 -0
- package/styleguide/render-notifications.ts +64 -0
- package/sys-note/element/delete-button.ts +78 -0
- package/tstemplate/constant-editor.ts +64 -0
- package/tstemplate/information-module.ts +31 -0
- package/tstemplate/template-analyzer.ts +77 -0
- package/viewpage/main.ts +253 -0
- package/workspaces/backend.ts +979 -0
- package/workspaces/preview.ts +232 -0
- package/workspaces/renderable/comment-view.ts +79 -0
- package/workspaces/renderable/diff-view.ts +58 -0
- package/workspaces/renderable/history-view.ts +97 -0
- package/workspaces/renderable/record-information.ts +118 -0
- package/workspaces/renderable/record-table.ts +355 -0
- package/workspaces/renderable/send-to-stage-form.ts +108 -0
- package/workspaces/toolbar/workspaces-menu.ts +190 -0
- package/workspaces/utility/icon-helper.ts +57 -0
- package/workspaces/workspaces.ts +136 -0
|
@@ -0,0 +1,525 @@
|
|
|
1
|
+
/*
|
|
2
|
+
* This file is part of the TYPO3 CMS project.
|
|
3
|
+
*
|
|
4
|
+
* It is free software; you can redistribute it and/or modify it under
|
|
5
|
+
* the terms of the GNU General Public License, either version 2
|
|
6
|
+
* of the License, or any later version.
|
|
7
|
+
*
|
|
8
|
+
* For the full copyright and license information, please read the
|
|
9
|
+
* LICENSE.txt file that was distributed with this source code.
|
|
10
|
+
*
|
|
11
|
+
* The TYPO3 project - inspiring people to share!
|
|
12
|
+
*/
|
|
13
|
+
|
|
14
|
+
import { html, LitElement, type TemplateResult } from 'lit';
|
|
15
|
+
import { customElement, state } from 'lit/decorators';
|
|
16
|
+
import Modal, { type ModalElement, Styles, Sizes } from '@typo3/backend/modal';
|
|
17
|
+
import { SeverityEnum } from './enum/severity';
|
|
18
|
+
import AjaxRequest from '@typo3/core/ajax/ajax-request';
|
|
19
|
+
import Notification from '@typo3/backend/notification';
|
|
20
|
+
import '@typo3/backend/element/progress-bar-element';
|
|
21
|
+
|
|
22
|
+
enum MarkupIdentifiers {
|
|
23
|
+
loginrefresh = 't3js-modal-loginrefresh',
|
|
24
|
+
lockedModal = 't3js-modal-backendlocked',
|
|
25
|
+
loginFormModal = 't3js-modal-backendloginform',
|
|
26
|
+
}
|
|
27
|
+
|
|
28
|
+
interface LoginRefreshOptions {
|
|
29
|
+
intervalTime?: number;
|
|
30
|
+
requestTokenUrl?: string;
|
|
31
|
+
loginFramesetUrl?: string;
|
|
32
|
+
logoutUrl?: string;
|
|
33
|
+
}
|
|
34
|
+
|
|
35
|
+
interface RequestTokenResponseData {
|
|
36
|
+
headerName?: string;
|
|
37
|
+
requestToken?: string;
|
|
38
|
+
}
|
|
39
|
+
|
|
40
|
+
/**
|
|
41
|
+
* Module: @typo3/backend/login-refresh
|
|
42
|
+
* @exports @typo3/backend/login-refresh
|
|
43
|
+
*/
|
|
44
|
+
class LoginRefresh {
|
|
45
|
+
private intervalTime: number = 60;
|
|
46
|
+
private intervalId: number = null;
|
|
47
|
+
private backendIsLocked: boolean = false;
|
|
48
|
+
private timeoutModal: ModalElement = null;
|
|
49
|
+
private backendLockedModal: ModalElement = null;
|
|
50
|
+
private loginForm: ModalElement = null;
|
|
51
|
+
private requestTokenUrl: string = '';
|
|
52
|
+
private loginFramesetUrl: string = '';
|
|
53
|
+
private logoutUrl: string = '';
|
|
54
|
+
|
|
55
|
+
/**
|
|
56
|
+
* Initialize login refresh
|
|
57
|
+
*/
|
|
58
|
+
public initialize(options?: LoginRefreshOptions): void {
|
|
59
|
+
if (typeof options === 'object') {
|
|
60
|
+
this.applyOptions(options);
|
|
61
|
+
}
|
|
62
|
+
this.startTask();
|
|
63
|
+
}
|
|
64
|
+
|
|
65
|
+
/**
|
|
66
|
+
* Start the task
|
|
67
|
+
*/
|
|
68
|
+
public startTask(): void {
|
|
69
|
+
if (this.intervalId !== null) {
|
|
70
|
+
return;
|
|
71
|
+
}
|
|
72
|
+
// set interval to 60 seconds
|
|
73
|
+
const interval: number = this.intervalTime * 1000;
|
|
74
|
+
this.intervalId = setInterval(this.checkActiveSession, interval);
|
|
75
|
+
}
|
|
76
|
+
|
|
77
|
+
/**
|
|
78
|
+
* Stop the task
|
|
79
|
+
*/
|
|
80
|
+
public stopTask(): void {
|
|
81
|
+
clearInterval(this.intervalId);
|
|
82
|
+
this.intervalId = null;
|
|
83
|
+
}
|
|
84
|
+
|
|
85
|
+
/**
|
|
86
|
+
* Set interval time
|
|
87
|
+
*
|
|
88
|
+
* @param {number} intervalTime
|
|
89
|
+
*/
|
|
90
|
+
public setIntervalTime(intervalTime: number): void {
|
|
91
|
+
// To avoid the integer overflow in setInterval, we limit the interval time to be one request per day
|
|
92
|
+
this.intervalTime = Math.min(intervalTime, 86400);
|
|
93
|
+
}
|
|
94
|
+
|
|
95
|
+
/**
|
|
96
|
+
* Set the logout URL
|
|
97
|
+
*
|
|
98
|
+
* @param {string} logoutUrl
|
|
99
|
+
*/
|
|
100
|
+
public setLogoutUrl(logoutUrl: string): void {
|
|
101
|
+
this.logoutUrl = logoutUrl;
|
|
102
|
+
}
|
|
103
|
+
|
|
104
|
+
/**
|
|
105
|
+
* Set login frameset url
|
|
106
|
+
*/
|
|
107
|
+
public setLoginFramesetUrl(loginFramesetUrl: string): void {
|
|
108
|
+
this.loginFramesetUrl = loginFramesetUrl;
|
|
109
|
+
}
|
|
110
|
+
|
|
111
|
+
/**
|
|
112
|
+
* Shows the timeout dialog. If the backend is not focused, a Web Notification
|
|
113
|
+
* is displayed, too.
|
|
114
|
+
*/
|
|
115
|
+
public showTimeoutModal(): void {
|
|
116
|
+
this.timeoutModal = this.createTimeoutModal();
|
|
117
|
+
this.timeoutModal.addEventListener('typo3-modal-hidden', () => this.timeoutModal = null);
|
|
118
|
+
this.timeoutModal.addEventListener('show-login-form', () => {
|
|
119
|
+
this.timeoutModal.hideModal();
|
|
120
|
+
this.showLoginForm();
|
|
121
|
+
});
|
|
122
|
+
}
|
|
123
|
+
|
|
124
|
+
/**
|
|
125
|
+
* Hides the timeout dialog. If a Web Notification is displayed, close it too.
|
|
126
|
+
*/
|
|
127
|
+
public hideTimeoutModal(): void {
|
|
128
|
+
this.timeoutModal?.hideModal();
|
|
129
|
+
}
|
|
130
|
+
|
|
131
|
+
/**
|
|
132
|
+
* Shows the "backend locked" dialog.
|
|
133
|
+
*/
|
|
134
|
+
public showBackendLockedModal(): void {
|
|
135
|
+
if (this.backendLockedModal) {
|
|
136
|
+
return;
|
|
137
|
+
}
|
|
138
|
+
this.backendLockedModal = this.createBackendLockedModal();
|
|
139
|
+
this.backendLockedModal.addEventListener('typo3-modal-hidden', () => this.backendLockedModal = null);
|
|
140
|
+
}
|
|
141
|
+
|
|
142
|
+
/**
|
|
143
|
+
* Hides the "backend locked" dialog.
|
|
144
|
+
*/
|
|
145
|
+
public hideBackendLockedModal(): void {
|
|
146
|
+
this.backendLockedModal?.hideModal();
|
|
147
|
+
}
|
|
148
|
+
|
|
149
|
+
/**
|
|
150
|
+
* Shows the login form.
|
|
151
|
+
*/
|
|
152
|
+
public showLoginForm(): void {
|
|
153
|
+
if (this.loginForm) {
|
|
154
|
+
return;
|
|
155
|
+
}
|
|
156
|
+
// log off for sure
|
|
157
|
+
new AjaxRequest(TYPO3.settings.ajaxUrls.logout).get().then((): void => {
|
|
158
|
+
if (TYPO3.configuration.showRefreshLoginPopup) {
|
|
159
|
+
this.showLoginPopup();
|
|
160
|
+
} else {
|
|
161
|
+
this.loginForm = this.createLoginFormModal();
|
|
162
|
+
this.loginForm.addEventListener('typo3-modal-hidden', () => this.loginForm = null);
|
|
163
|
+
}
|
|
164
|
+
});
|
|
165
|
+
}
|
|
166
|
+
|
|
167
|
+
/**
|
|
168
|
+
* Opens the login form in a new window.
|
|
169
|
+
*/
|
|
170
|
+
public showLoginPopup(): void {
|
|
171
|
+
const vHWin = window.open(
|
|
172
|
+
this.loginFramesetUrl,
|
|
173
|
+
'relogin_' + Math.random().toString(16).slice(2),
|
|
174
|
+
'height=450,width=700,status=0,menubar=0,location=1',
|
|
175
|
+
);
|
|
176
|
+
if (vHWin) {
|
|
177
|
+
vHWin.focus();
|
|
178
|
+
}
|
|
179
|
+
}
|
|
180
|
+
|
|
181
|
+
/**
|
|
182
|
+
* Hides the login form.
|
|
183
|
+
*/
|
|
184
|
+
public hideLoginForm(): void {
|
|
185
|
+
this.loginForm?.hideModal();
|
|
186
|
+
}
|
|
187
|
+
|
|
188
|
+
/**
|
|
189
|
+
* Generates the modal displayed if the backend is locked.
|
|
190
|
+
*/
|
|
191
|
+
protected createBackendLockedModal(): ModalElement {
|
|
192
|
+
return Modal.advanced({
|
|
193
|
+
additionalCssClasses: [ MarkupIdentifiers.lockedModal ],
|
|
194
|
+
title: TYPO3.lang['mess.please_wait'],
|
|
195
|
+
severity: SeverityEnum.notice,
|
|
196
|
+
style: Styles.light,
|
|
197
|
+
size: Sizes.small,
|
|
198
|
+
staticBackdrop: true,
|
|
199
|
+
hideCloseButton: true,
|
|
200
|
+
content: html`
|
|
201
|
+
<p>${TYPO3.lang['mess.be_locked']}</p>
|
|
202
|
+
`
|
|
203
|
+
});
|
|
204
|
+
}
|
|
205
|
+
|
|
206
|
+
/**
|
|
207
|
+
* Generates the modal displayed on near session time outs
|
|
208
|
+
*/
|
|
209
|
+
protected createTimeoutModal(): ModalElement {
|
|
210
|
+
const modal = Modal.advanced({
|
|
211
|
+
additionalCssClasses: [ MarkupIdentifiers.loginrefresh ],
|
|
212
|
+
title: TYPO3.lang['mess.login_about_to_expire_title'],
|
|
213
|
+
severity: SeverityEnum.notice,
|
|
214
|
+
style: Styles.light,
|
|
215
|
+
size: Sizes.small,
|
|
216
|
+
staticBackdrop: true,
|
|
217
|
+
hideCloseButton: true,
|
|
218
|
+
buttons: [
|
|
219
|
+
{
|
|
220
|
+
text: TYPO3.lang['mess.refresh_login_logout_button'],
|
|
221
|
+
active: false,
|
|
222
|
+
btnClass: 'btn-default',
|
|
223
|
+
name: 'logout',
|
|
224
|
+
trigger: () => top.location.href = this.logoutUrl
|
|
225
|
+
},
|
|
226
|
+
{
|
|
227
|
+
text: TYPO3.lang['mess.refresh_login_refresh_button'],
|
|
228
|
+
active: true,
|
|
229
|
+
btnClass: 'btn-primary',
|
|
230
|
+
name: 'refreshSession',
|
|
231
|
+
trigger: async (e: Event, modal: ModalElement) => {
|
|
232
|
+
const response = await new AjaxRequest(TYPO3.settings.ajaxUrls.login_refresh).get();
|
|
233
|
+
const data = await response.resolve();
|
|
234
|
+
modal.hideModal();
|
|
235
|
+
if (!data.refresh.success) {
|
|
236
|
+
modal.dispatchEvent(new Event('show-login-form'));
|
|
237
|
+
}
|
|
238
|
+
}
|
|
239
|
+
}
|
|
240
|
+
],
|
|
241
|
+
content: html`
|
|
242
|
+
<p>${TYPO3.lang['mess.login_about_to_expire']}</p>
|
|
243
|
+
<typo3-login-refresh-progress-bar
|
|
244
|
+
@progress-bar-overdue=${() => modal.dispatchEvent(new Event('show-login-form'))}
|
|
245
|
+
></typo3-login-refresh-progress-bar>
|
|
246
|
+
`
|
|
247
|
+
});
|
|
248
|
+
|
|
249
|
+
modal.addEventListener('typo3-modal-hidden', (): void => {
|
|
250
|
+
this.startTask();
|
|
251
|
+
});
|
|
252
|
+
|
|
253
|
+
modal.addEventListener('typo3-modal-shown', (): void => {
|
|
254
|
+
this.stopTask();
|
|
255
|
+
});
|
|
256
|
+
|
|
257
|
+
return modal;
|
|
258
|
+
}
|
|
259
|
+
|
|
260
|
+
/**
|
|
261
|
+
* Generates the login form displayed if the session has timed out.
|
|
262
|
+
*/
|
|
263
|
+
protected createLoginFormModal(): ModalElement {
|
|
264
|
+
const refresh_login_title = String(TYPO3.lang['mess.refresh_login_title']).replace('%s', TYPO3.configuration.username);
|
|
265
|
+
const modal = Modal.advanced({
|
|
266
|
+
additionalCssClasses: [ MarkupIdentifiers.loginFormModal ],
|
|
267
|
+
title: refresh_login_title,
|
|
268
|
+
severity: SeverityEnum.notice,
|
|
269
|
+
style: Styles.light,
|
|
270
|
+
size: Sizes.small,
|
|
271
|
+
staticBackdrop: true,
|
|
272
|
+
hideCloseButton: true,
|
|
273
|
+
buttons: [
|
|
274
|
+
{
|
|
275
|
+
text: TYPO3.lang['mess.refresh_exit_button'],
|
|
276
|
+
active: false,
|
|
277
|
+
btnClass: 'btn-default',
|
|
278
|
+
name: 'logout',
|
|
279
|
+
trigger: () => top.location.href = this.logoutUrl
|
|
280
|
+
},
|
|
281
|
+
{
|
|
282
|
+
text: TYPO3.lang['mess.refresh_login_button'],
|
|
283
|
+
active: false,
|
|
284
|
+
btnClass: 'btn-primary',
|
|
285
|
+
name: 'refreshSession',
|
|
286
|
+
trigger: async (e: Event, modal: ModalElement) => {
|
|
287
|
+
modal.querySelector('form').requestSubmit();
|
|
288
|
+
const response = await new AjaxRequest(TYPO3.settings.ajaxUrls.login_refresh).get();
|
|
289
|
+
const data = await response.resolve();
|
|
290
|
+
modal.hideModal();
|
|
291
|
+
if (!data.refresh.success) {
|
|
292
|
+
modal.dispatchEvent(new Event('show-login-form'));
|
|
293
|
+
}
|
|
294
|
+
}
|
|
295
|
+
}
|
|
296
|
+
],
|
|
297
|
+
content: html`
|
|
298
|
+
<p>${TYPO3.lang['mess.login_expired']}</p>
|
|
299
|
+
<form
|
|
300
|
+
id="beLoginRefresh"
|
|
301
|
+
method="POST"
|
|
302
|
+
action=${TYPO3.settings.ajaxUrls.login}
|
|
303
|
+
@submit=${(e: SubmitEvent) => this.submitForm(e, e.currentTarget as HTMLFormElement)}>
|
|
304
|
+
<div>
|
|
305
|
+
<input
|
|
306
|
+
type="text"
|
|
307
|
+
name="username"
|
|
308
|
+
class="d-none"
|
|
309
|
+
autocomplete="username"
|
|
310
|
+
.value=${TYPO3.configuration.username}>
|
|
311
|
+
<input
|
|
312
|
+
type="hidden"
|
|
313
|
+
name="userident"
|
|
314
|
+
id="t3-loginrefresh-userident">
|
|
315
|
+
</div>
|
|
316
|
+
<div class="form-group">
|
|
317
|
+
<input
|
|
318
|
+
type="password"
|
|
319
|
+
name="p_field"
|
|
320
|
+
autofocus
|
|
321
|
+
class="form-control"
|
|
322
|
+
autocomplete="current-password"
|
|
323
|
+
placeholder=${TYPO3.lang['mess.refresh_login_password']}>
|
|
324
|
+
</div>
|
|
325
|
+
</form>
|
|
326
|
+
`
|
|
327
|
+
});
|
|
328
|
+
|
|
329
|
+
modal.addEventListener('typo3-modal-hidden', (): void => {
|
|
330
|
+
this.startTask();
|
|
331
|
+
});
|
|
332
|
+
|
|
333
|
+
modal.addEventListener('typo3-modal-shown', (): void => {
|
|
334
|
+
this.stopTask();
|
|
335
|
+
});
|
|
336
|
+
|
|
337
|
+
return modal;
|
|
338
|
+
}
|
|
339
|
+
|
|
340
|
+
/**
|
|
341
|
+
* Creates additional data based on the security level and "submits" the form
|
|
342
|
+
* via an AJAX request.
|
|
343
|
+
*/
|
|
344
|
+
protected submitForm = async (event: SubmitEvent, form: HTMLFormElement): Promise<void> => {
|
|
345
|
+
event.preventDefault();
|
|
346
|
+
|
|
347
|
+
const tokenResponse = await new AjaxRequest(this.requestTokenUrl).post({});
|
|
348
|
+
const tokenData: RequestTokenResponseData = await tokenResponse.resolve('application/json');
|
|
349
|
+
|
|
350
|
+
if (!tokenData.headerName || !tokenData.requestToken) {
|
|
351
|
+
return;
|
|
352
|
+
}
|
|
353
|
+
const passwordField = form.querySelector('input[name=p_field]') as HTMLInputElement;
|
|
354
|
+
const useridentField = form.querySelector('input[name=userident]') as HTMLInputElement;
|
|
355
|
+
const passwordFieldValue = passwordField.value;
|
|
356
|
+
|
|
357
|
+
if (passwordFieldValue === '' && useridentField.value === '') {
|
|
358
|
+
Notification.error(TYPO3.lang['mess.refresh_login_failed'], TYPO3.lang['mess.refresh_login_emptyPassword']);
|
|
359
|
+
passwordField.focus();
|
|
360
|
+
return;
|
|
361
|
+
}
|
|
362
|
+
|
|
363
|
+
if (passwordFieldValue) {
|
|
364
|
+
useridentField.value = passwordFieldValue;
|
|
365
|
+
passwordField.value = '';
|
|
366
|
+
}
|
|
367
|
+
|
|
368
|
+
const postData: Record<string, string> = {
|
|
369
|
+
login_status: 'login'
|
|
370
|
+
};
|
|
371
|
+
for (const [name, value] of new FormData(form)) {
|
|
372
|
+
postData[name] = value.toString();
|
|
373
|
+
}
|
|
374
|
+
const headers = new Headers();
|
|
375
|
+
headers.set(tokenData.headerName, tokenData.requestToken);
|
|
376
|
+
|
|
377
|
+
const response = await new AjaxRequest(form.getAttribute('action')).post(postData, { headers });
|
|
378
|
+
const data = await response.resolve();
|
|
379
|
+
if (data.login.success) {
|
|
380
|
+
// User is logged in
|
|
381
|
+
this.hideLoginForm();
|
|
382
|
+
} else {
|
|
383
|
+
Notification.error(TYPO3.lang['mess.refresh_login_failed'], TYPO3.lang['mess.refresh_login_failed_message']);
|
|
384
|
+
passwordField.focus();
|
|
385
|
+
}
|
|
386
|
+
};
|
|
387
|
+
|
|
388
|
+
/**
|
|
389
|
+
* Periodically called task that checks if
|
|
390
|
+
*
|
|
391
|
+
* - the user's backend session is about to expire
|
|
392
|
+
* - the user's backend session has expired
|
|
393
|
+
* - the backend got locked
|
|
394
|
+
*
|
|
395
|
+
* and opens a dialog.
|
|
396
|
+
*/
|
|
397
|
+
protected checkActiveSession = async (): Promise<void> => {
|
|
398
|
+
try {
|
|
399
|
+
const response = await new AjaxRequest(TYPO3.settings.ajaxUrls.login_timedout).get();
|
|
400
|
+
const data = await response.resolve();
|
|
401
|
+
if (data.login.locked) {
|
|
402
|
+
if (!this.backendIsLocked) {
|
|
403
|
+
this.backendIsLocked = true;
|
|
404
|
+
this.showBackendLockedModal();
|
|
405
|
+
}
|
|
406
|
+
} else {
|
|
407
|
+
if (this.backendIsLocked) {
|
|
408
|
+
this.backendIsLocked = false;
|
|
409
|
+
this.hideBackendLockedModal();
|
|
410
|
+
}
|
|
411
|
+
}
|
|
412
|
+
|
|
413
|
+
if (!this.backendIsLocked) {
|
|
414
|
+
if (data.login.timed_out || data.login.will_time_out) {
|
|
415
|
+
if (data.login.timed_out) {
|
|
416
|
+
this.showLoginForm();
|
|
417
|
+
} else {
|
|
418
|
+
this.showTimeoutModal();
|
|
419
|
+
}
|
|
420
|
+
}
|
|
421
|
+
}
|
|
422
|
+
} catch {
|
|
423
|
+
this.backendIsLocked = true;
|
|
424
|
+
this.showBackendLockedModal();
|
|
425
|
+
}
|
|
426
|
+
};
|
|
427
|
+
|
|
428
|
+
private applyOptions(options: LoginRefreshOptions): void {
|
|
429
|
+
if (options.intervalTime !== undefined) {
|
|
430
|
+
this.setIntervalTime(options.intervalTime);
|
|
431
|
+
}
|
|
432
|
+
if (options.loginFramesetUrl !== undefined) {
|
|
433
|
+
this.setLoginFramesetUrl(options.loginFramesetUrl);
|
|
434
|
+
}
|
|
435
|
+
if (options.logoutUrl !== undefined) {
|
|
436
|
+
this.setLogoutUrl(options.logoutUrl);
|
|
437
|
+
}
|
|
438
|
+
if (options.requestTokenUrl !== undefined) {
|
|
439
|
+
this.requestTokenUrl = options.requestTokenUrl;
|
|
440
|
+
}
|
|
441
|
+
}
|
|
442
|
+
}
|
|
443
|
+
|
|
444
|
+
@customElement('typo3-login-refresh-progress-bar')
|
|
445
|
+
export class SelfFillingProgressBarElement extends LitElement {
|
|
446
|
+
@state()
|
|
447
|
+
protected current = 0;
|
|
448
|
+
|
|
449
|
+
private readonly max = 100;
|
|
450
|
+
private intervalId: number;
|
|
451
|
+
|
|
452
|
+
public override connectedCallback(): void {
|
|
453
|
+
super.connectedCallback();
|
|
454
|
+
if (this.intervalId) {
|
|
455
|
+
clearInterval(this.intervalId);
|
|
456
|
+
}
|
|
457
|
+
this.intervalId = setInterval(this.advanceProgressBar, 300);
|
|
458
|
+
}
|
|
459
|
+
|
|
460
|
+
public override disconnectedCallback(): void {
|
|
461
|
+
super.disconnectedCallback();
|
|
462
|
+
if (this.intervalId) {
|
|
463
|
+
clearInterval(this.intervalId);
|
|
464
|
+
this.intervalId = null;
|
|
465
|
+
}
|
|
466
|
+
}
|
|
467
|
+
|
|
468
|
+
protected override createRenderRoot(): HTMLElement | ShadowRoot {
|
|
469
|
+
return this;
|
|
470
|
+
}
|
|
471
|
+
|
|
472
|
+
protected override render(): TemplateResult {
|
|
473
|
+
return html`
|
|
474
|
+
<typo3-backend-progress-bar value=${100 - this.current} max="100"></typo3-backend-progress-bar>
|
|
475
|
+
`;
|
|
476
|
+
}
|
|
477
|
+
|
|
478
|
+
private readonly advanceProgressBar = () => {
|
|
479
|
+
this.current++;
|
|
480
|
+
const isOverdue = (this.current >= this.max);
|
|
481
|
+
if (isOverdue) {
|
|
482
|
+
this.dispatchEvent(new Event('progress-bar-overdue'));
|
|
483
|
+
}
|
|
484
|
+
};
|
|
485
|
+
}
|
|
486
|
+
|
|
487
|
+
let loginRefreshObject;
|
|
488
|
+
try {
|
|
489
|
+
// fetch from opening window
|
|
490
|
+
if (window.opener && window.opener.TYPO3 && window.opener.TYPO3.LoginRefresh) {
|
|
491
|
+
loginRefreshObject = window.opener.TYPO3.LoginRefresh;
|
|
492
|
+
}
|
|
493
|
+
|
|
494
|
+
// fetch from parent
|
|
495
|
+
if (parent && parent.window.TYPO3 && parent.window.TYPO3.LoginRefresh) {
|
|
496
|
+
loginRefreshObject = parent.window.TYPO3.LoginRefresh;
|
|
497
|
+
}
|
|
498
|
+
|
|
499
|
+
// fetch object from outer frame
|
|
500
|
+
if (top && top.TYPO3 && top.TYPO3.LoginRefresh) {
|
|
501
|
+
loginRefreshObject = top.TYPO3.LoginRefresh;
|
|
502
|
+
}
|
|
503
|
+
} catch {
|
|
504
|
+
// This only happens if the opener, parent or top is some other url (eg a local file)
|
|
505
|
+
// which loaded the current window. Then the browser's cross domain policy jumps in
|
|
506
|
+
// and raises an exception.
|
|
507
|
+
// For this case we are safe and we can create our global object below.
|
|
508
|
+
}
|
|
509
|
+
|
|
510
|
+
if (!loginRefreshObject) {
|
|
511
|
+
loginRefreshObject = new LoginRefresh();
|
|
512
|
+
|
|
513
|
+
// attach to global frame
|
|
514
|
+
if (typeof TYPO3 !== 'undefined') {
|
|
515
|
+
TYPO3.LoginRefresh = loginRefreshObject;
|
|
516
|
+
}
|
|
517
|
+
}
|
|
518
|
+
|
|
519
|
+
export default loginRefreshObject;
|
|
520
|
+
|
|
521
|
+
declare global {
|
|
522
|
+
interface HTMLElementTagNameMap {
|
|
523
|
+
'typo3-login-refresh-progress-bar': SelfFillingProgressBarElement;
|
|
524
|
+
}
|
|
525
|
+
}
|
package/backend/login.ts
ADDED
|
@@ -0,0 +1,179 @@
|
|
|
1
|
+
/*
|
|
2
|
+
* This file is part of the TYPO3 CMS project.
|
|
3
|
+
*
|
|
4
|
+
* It is free software; you can redistribute it and/or modify it under
|
|
5
|
+
* the terms of the GNU General Public License, either version 2
|
|
6
|
+
* of the License, or any later version.
|
|
7
|
+
*
|
|
8
|
+
* For the full copyright and license information, please read the
|
|
9
|
+
* LICENSE.txt file that was distributed with this source code.
|
|
10
|
+
*
|
|
11
|
+
* The TYPO3 project - inspiring people to share!
|
|
12
|
+
*/
|
|
13
|
+
|
|
14
|
+
import 'bootstrap';
|
|
15
|
+
import '@typo3/backend/input/clearable';
|
|
16
|
+
import AjaxRequest from '@typo3/core/ajax/ajax-request';
|
|
17
|
+
import type { AjaxResponse } from '@typo3/core/ajax/ajax-response';
|
|
18
|
+
import RegularEvent from '@typo3/core/event/regular-event';
|
|
19
|
+
import DocumentService from '@typo3/core/document-service';
|
|
20
|
+
|
|
21
|
+
interface PreflightResponse {
|
|
22
|
+
capabilities: PreflightResponseCapabilities;
|
|
23
|
+
}
|
|
24
|
+
|
|
25
|
+
interface PreflightResponseCapabilities {
|
|
26
|
+
cookie: boolean,
|
|
27
|
+
referrer: boolean
|
|
28
|
+
}
|
|
29
|
+
|
|
30
|
+
/**
|
|
31
|
+
* Module: @typo3/backend/login
|
|
32
|
+
* JavaScript module for the backend login form
|
|
33
|
+
* @exports @typo3/backend/login
|
|
34
|
+
*
|
|
35
|
+
* Class and file name do not match as the class was renamed, but to keep overrides in place, the filename has to stay!
|
|
36
|
+
*/
|
|
37
|
+
class BackendLogin {
|
|
38
|
+
public options: any;
|
|
39
|
+
public ready: boolean = true;
|
|
40
|
+
|
|
41
|
+
constructor() {
|
|
42
|
+
this.options = {
|
|
43
|
+
error: '.t3js-login-error',
|
|
44
|
+
errorNoCookies: '.t3js-login-error-nocookies',
|
|
45
|
+
errorNoReferrer: '.t3js-login-error-noreferrer',
|
|
46
|
+
formFields: '.t3js-login-formfields',
|
|
47
|
+
loginForm: '#typo3-login-form',
|
|
48
|
+
loginUrlLink: 't3js-login-url',
|
|
49
|
+
submitButton: '.t3js-login-submit',
|
|
50
|
+
submitHandler: null,
|
|
51
|
+
useridentField: '.t3js-login-userident-field',
|
|
52
|
+
};
|
|
53
|
+
|
|
54
|
+
this.checkLoginRefresh();
|
|
55
|
+
this.checkCookieSupport();
|
|
56
|
+
this.checkDocumentReferrerSupport();
|
|
57
|
+
this.initializeEvents();
|
|
58
|
+
|
|
59
|
+
// prevent opening the login form in the backend frameset
|
|
60
|
+
if (top.location.href !== location.href) {
|
|
61
|
+
this.ready = false;
|
|
62
|
+
top.location.href = location.href;
|
|
63
|
+
}
|
|
64
|
+
if (this.ready) {
|
|
65
|
+
document.body.setAttribute('data-typo3-login-ready', 'true');
|
|
66
|
+
}
|
|
67
|
+
}
|
|
68
|
+
|
|
69
|
+
/**
|
|
70
|
+
* Hide all form fields and show a progress message and icon
|
|
71
|
+
*/
|
|
72
|
+
private showLoginProcess(): void {
|
|
73
|
+
this.showLoadingIndicator();
|
|
74
|
+
document.querySelector(this.options.error)?.classList.add('hidden');
|
|
75
|
+
document.querySelector(this.options.errorNoCookies)?.classList.add('hidden');
|
|
76
|
+
}
|
|
77
|
+
|
|
78
|
+
/**
|
|
79
|
+
* Show the loading spinner in the submit button
|
|
80
|
+
*/
|
|
81
|
+
private showLoadingIndicator(): void {
|
|
82
|
+
const button = document.querySelector(this.options.submitButton) as HTMLButtonElement;
|
|
83
|
+
button.innerHTML = button.dataset.loadingText;
|
|
84
|
+
}
|
|
85
|
+
|
|
86
|
+
/**
|
|
87
|
+
* Pass on to registered submit handler
|
|
88
|
+
*
|
|
89
|
+
* @param {Event} event
|
|
90
|
+
*/
|
|
91
|
+
private handleSubmit(event: Event): void {
|
|
92
|
+
this.showLoginProcess();
|
|
93
|
+
|
|
94
|
+
if (typeof this.options.submitHandler === 'function') {
|
|
95
|
+
this.options.submitHandler(event);
|
|
96
|
+
}
|
|
97
|
+
}
|
|
98
|
+
|
|
99
|
+
private checkDocumentReferrerSupport(): void {
|
|
100
|
+
const loginUrlLink = document.getElementById(this.options.loginUrlLink) as HTMLAnchorElement;
|
|
101
|
+
// skip referrer check if explicitly disabled
|
|
102
|
+
if (loginUrlLink !== null
|
|
103
|
+
&& typeof loginUrlLink.dataset.referrerCheckEnabled === 'undefined'
|
|
104
|
+
&& loginUrlLink.dataset.referrerCheckEnabled !== '1'
|
|
105
|
+
) {
|
|
106
|
+
return;
|
|
107
|
+
}
|
|
108
|
+
if (typeof TYPO3.settings === 'undefined' || typeof TYPO3.settings.ajaxUrls === 'undefined') {
|
|
109
|
+
return;
|
|
110
|
+
}
|
|
111
|
+
new AjaxRequest(TYPO3.settings.ajaxUrls.login_preflight).get()
|
|
112
|
+
.then(async (response: AjaxResponse) => {
|
|
113
|
+
const result = await response.resolve('application/json') as PreflightResponse;
|
|
114
|
+
if (result.capabilities.referrer !== true) {
|
|
115
|
+
document.querySelectorAll(this.options.errorNoReferrer)
|
|
116
|
+
.forEach((element: HTMLElement): void => element.classList.remove('hidden'));
|
|
117
|
+
}
|
|
118
|
+
});
|
|
119
|
+
}
|
|
120
|
+
|
|
121
|
+
/**
|
|
122
|
+
* Hides input fields and shows cookie warning
|
|
123
|
+
*/
|
|
124
|
+
private showCookieWarning(): void {
|
|
125
|
+
document.querySelector(this.options.formFields)?.classList.add('hidden');
|
|
126
|
+
document.querySelector(this.options.errorNoCookies)?.classList.remove('hidden');
|
|
127
|
+
}
|
|
128
|
+
|
|
129
|
+
private checkLoginRefresh(): void {
|
|
130
|
+
const loginRefresh = document.querySelector(this.options.loginForm + ' input[name="loginRefresh"]');
|
|
131
|
+
if (loginRefresh instanceof HTMLInputElement && loginRefresh.value) {
|
|
132
|
+
if (window.opener && window.opener.TYPO3 && window.opener.TYPO3.LoginRefresh) {
|
|
133
|
+
window.opener.TYPO3.LoginRefresh.startTask();
|
|
134
|
+
window.close();
|
|
135
|
+
}
|
|
136
|
+
}
|
|
137
|
+
}
|
|
138
|
+
|
|
139
|
+
/**
|
|
140
|
+
* Checks browser's cookie support
|
|
141
|
+
* see http://stackoverflow.com/questions/8112634/jquery-detecting-cookies-enabled
|
|
142
|
+
*/
|
|
143
|
+
private checkCookieSupport(): void {
|
|
144
|
+
const cookieEnabled = navigator.cookieEnabled;
|
|
145
|
+
|
|
146
|
+
// when cookieEnabled flag is present and false then cookies are disabled.
|
|
147
|
+
if (cookieEnabled === false) {
|
|
148
|
+
this.showCookieWarning();
|
|
149
|
+
} else {
|
|
150
|
+
// try to set a test cookie if we can't see any cookies and we're using
|
|
151
|
+
// either a browser that doesn't support navigator.cookieEnabled
|
|
152
|
+
// or IE (which always returns true for navigator.cookieEnabled)
|
|
153
|
+
if (!document.cookie && (cookieEnabled === null || /*@cc_on!@*/false)) {
|
|
154
|
+
document.cookie = 'typo3-login-cookiecheck=1';
|
|
155
|
+
|
|
156
|
+
if (!document.cookie) {
|
|
157
|
+
this.showCookieWarning();
|
|
158
|
+
} else {
|
|
159
|
+
// unset the cookie again
|
|
160
|
+
document.cookie = 'typo3-login-cookiecheck=; expires=' + new Date(0).toUTCString();
|
|
161
|
+
}
|
|
162
|
+
}
|
|
163
|
+
}
|
|
164
|
+
}
|
|
165
|
+
|
|
166
|
+
/**
|
|
167
|
+
* Registers listeners for the Login Interface
|
|
168
|
+
*/
|
|
169
|
+
private async initializeEvents(): Promise<void> {
|
|
170
|
+
await DocumentService.ready();
|
|
171
|
+
new RegularEvent('submit', this.handleSubmit.bind(this)).bindTo(document.querySelector(this.options.loginForm));
|
|
172
|
+
|
|
173
|
+
(document.querySelectorAll('.t3js-clearable') as NodeListOf<HTMLInputElement>).forEach(
|
|
174
|
+
(clearableField: HTMLInputElement) => clearableField.clearable(),
|
|
175
|
+
);
|
|
176
|
+
}
|
|
177
|
+
}
|
|
178
|
+
|
|
179
|
+
export default new BackendLogin();
|