diff --git a/e2e-tests/playwright/support/server/default_config.ts b/e2e-tests/playwright/support/server/default_config.ts index 4bcfdd57984..211ec381bad 100644 --- a/e2e-tests/playwright/support/server/default_config.ts +++ b/e2e-tests/playwright/support/server/default_config.ts @@ -530,7 +530,6 @@ const defaultServerConfig: AdminConfig = { EnableSharedChannels: false, EnableRemoteClusterService: false, EnableAppBar: false, - PatchPluginsReactDOM: false, DisableRefetchingOnBrowserFocus: false, DelayChannelAutocomplete: false, }, diff --git a/server/channels/app/plugin.go b/server/channels/app/plugin.go index 95c4fc5caec..e6f5c2a4de6 100644 --- a/server/channels/app/plugin.go +++ b/server/channels/app/plugin.go @@ -231,7 +231,6 @@ func (ch *Channels) initPlugins(c *request.Context, pluginDir, webappPluginDir s NewDriverImpl(ch.srv), pluginDir, webappPluginDir, - *ch.cfgSvc.Config().ExperimentalSettings.PatchPluginsReactDOM, ch.srv.Log(), ch.srv.GetMetrics(), ) diff --git a/server/channels/app/plugin_api_test.go b/server/channels/app/plugin_api_test.go index 2ba65aa5f93..4c9fa41eadf 100644 --- a/server/channels/app/plugin_api_test.go +++ b/server/channels/app/plugin_api_test.go @@ -92,7 +92,7 @@ func setupMultiPluginAPITest(t *testing.T, pluginCodes []string, pluginManifests return app.NewPluginAPI(c, manifest) } - env, err := plugin.NewEnvironment(newPluginAPI, NewDriverImpl(app.Srv()), pluginDir, webappPluginDir, false, app.Log(), nil) + env, err := plugin.NewEnvironment(newPluginAPI, NewDriverImpl(app.Srv()), pluginDir, webappPluginDir, app.Log(), nil) require.NoError(t, err) require.Equal(t, len(pluginCodes), len(pluginIDs)) @@ -849,7 +849,7 @@ func TestPluginAPIGetPlugins(t *testing.T) { defer os.RemoveAll(pluginDir) defer os.RemoveAll(webappPluginDir) - env, err := plugin.NewEnvironment(th.NewPluginAPI, NewDriverImpl(th.Server), pluginDir, webappPluginDir, false, th.App.Log(), nil) + env, err := plugin.NewEnvironment(th.NewPluginAPI, NewDriverImpl(th.Server), pluginDir, webappPluginDir, th.App.Log(), nil) require.NoError(t, err) pluginIDs := []string{"pluginid1", "pluginid2", "pluginid3"} @@ -937,7 +937,7 @@ func TestInstallPlugin(t *testing.T) { return app.NewPluginAPI(c, manifest) } - env, err := plugin.NewEnvironment(newPluginAPI, NewDriverImpl(app.Srv()), pluginDir, webappPluginDir, false, app.Log(), nil) + env, err := plugin.NewEnvironment(newPluginAPI, NewDriverImpl(app.Srv()), pluginDir, webappPluginDir, app.Log(), nil) require.NoError(t, err) app.ch.SetPluginsEnvironment(env) @@ -1632,7 +1632,7 @@ func TestAPIMetrics(t *testing.T) { defer os.RemoveAll(pluginDir) defer os.RemoveAll(webappPluginDir) - env, err := plugin.NewEnvironment(th.NewPluginAPI, NewDriverImpl(th.Server), pluginDir, webappPluginDir, false, th.App.Log(), metricsMock) + env, err := plugin.NewEnvironment(th.NewPluginAPI, NewDriverImpl(th.Server), pluginDir, webappPluginDir, th.App.Log(), metricsMock) require.NoError(t, err) th.App.ch.SetPluginsEnvironment(env) @@ -2079,7 +2079,7 @@ func TestRegisterCollectionAndTopic(t *testing.T) { return th.App.NewPluginAPI(th.Context, manifest) } - env, err := plugin.NewEnvironment(newPluginAPI, NewDriverImpl(th.App.Srv()), pluginDir, webappPluginDir, false, th.App.Log(), nil) + env, err := plugin.NewEnvironment(newPluginAPI, NewDriverImpl(th.App.Srv()), pluginDir, webappPluginDir, th.App.Log(), nil) require.NoError(t, err) th.App.ch.SetPluginsEnvironment(env) @@ -2179,7 +2179,7 @@ func TestPluginUploadsAPI(t *testing.T) { newPluginAPI := func(manifest *model.Manifest) plugin.API { return th.App.NewPluginAPI(th.Context, manifest) } - env, err := plugin.NewEnvironment(newPluginAPI, NewDriverImpl(th.App.Srv()), pluginDir, webappPluginDir, false, th.App.Log(), nil) + env, err := plugin.NewEnvironment(newPluginAPI, NewDriverImpl(th.App.Srv()), pluginDir, webappPluginDir, th.App.Log(), nil) require.NoError(t, err) th.App.ch.SetPluginsEnvironment(env) diff --git a/server/channels/app/plugin_hooks_test.go b/server/channels/app/plugin_hooks_test.go index 0238457662b..3dc5e50ee34 100644 --- a/server/channels/app/plugin_hooks_test.go +++ b/server/channels/app/plugin_hooks_test.go @@ -33,7 +33,7 @@ func SetAppEnvironmentWithPlugins(t *testing.T, pluginCode []string, app *App, a webappPluginDir, err := os.MkdirTemp("", "") require.NoError(t, err) - env, err := plugin.NewEnvironment(apiFunc, NewDriverImpl(app.Srv()), pluginDir, webappPluginDir, false, app.Log(), nil) + env, err := plugin.NewEnvironment(apiFunc, NewDriverImpl(app.Srv()), pluginDir, webappPluginDir, app.Log(), nil) require.NoError(t, err) app.ch.SetPluginsEnvironment(env) @@ -1030,7 +1030,7 @@ func TestHookMetrics(t *testing.T) { defer os.RemoveAll(pluginDir) defer os.RemoveAll(webappPluginDir) - env, err := plugin.NewEnvironment(th.NewPluginAPI, NewDriverImpl(th.Server), pluginDir, webappPluginDir, false, th.App.Log(), metricsMock) + env, err := plugin.NewEnvironment(th.NewPluginAPI, NewDriverImpl(th.Server), pluginDir, webappPluginDir, th.App.Log(), metricsMock) require.NoError(t, err) th.App.ch.SetPluginsEnvironment(env) diff --git a/server/channels/web/web_test.go b/server/channels/web/web_test.go index 2c4fb8d229f..c6d9d46fbdd 100644 --- a/server/channels/web/web_test.go +++ b/server/channels/web/web_test.go @@ -283,7 +283,7 @@ func TestPublicFilesRequest(t *testing.T) { defer os.RemoveAll(pluginDir) defer os.RemoveAll(webappPluginDir) - env, err := plugin.NewEnvironment(th.NewPluginAPI, app.NewDriverImpl(th.Server), pluginDir, webappPluginDir, false, th.App.Log(), nil) + env, err := plugin.NewEnvironment(th.NewPluginAPI, app.NewDriverImpl(th.Server), pluginDir, webappPluginDir, th.App.Log(), nil) require.NoError(t, err) pluginID := "com.mattermost.sample" diff --git a/server/model/config.go b/server/model/config.go index 7bd69d00db7..6fe686d5e5e 100644 --- a/server/model/config.go +++ b/server/model/config.go @@ -971,7 +971,6 @@ type ExperimentalSettings struct { EnableSharedChannels *bool `access:"experimental_features"` EnableRemoteClusterService *bool `access:"experimental_features"` EnableAppBar *bool `access:"experimental_features"` - PatchPluginsReactDOM *bool `access:"experimental_features"` DisableRefetchingOnBrowserFocus *bool `access:"experimental_features"` DelayChannelAutocomplete *bool `access:"experimental_features"` } @@ -1009,10 +1008,6 @@ func (s *ExperimentalSettings) SetDefaults() { s.EnableAppBar = NewBool(false) } - if s.PatchPluginsReactDOM == nil { - s.PatchPluginsReactDOM = NewBool(false) - } - if s.DisableRefetchingOnBrowserFocus == nil { s.DisableRefetchingOnBrowserFocus = NewBool(false) } diff --git a/server/platform/services/telemetry/telemetry.go b/server/platform/services/telemetry/telemetry.go index 6982904d15e..e260cdfa904 100644 --- a/server/platform/services/telemetry/telemetry.go +++ b/server/platform/services/telemetry/telemetry.go @@ -758,7 +758,6 @@ func (ts *TelemetryService) trackConfig() { "enable_shared_channels": *cfg.ExperimentalSettings.EnableSharedChannels, "enable_remote_cluster_service": *cfg.ExperimentalSettings.EnableRemoteClusterService && cfg.FeatureFlags.EnableRemoteClusterService, "enable_app_bar": *cfg.ExperimentalSettings.EnableAppBar, - "patch_plugins_react_dom": *cfg.ExperimentalSettings.PatchPluginsReactDOM, "disable_refetching_on_browser_focus": *cfg.ExperimentalSettings.DisableRefetchingOnBrowserFocus, "delay_channel_autocomplete": *cfg.ExperimentalSettings.DelayChannelAutocomplete, }) diff --git a/server/platform/services/telemetry/telemetry_test.go b/server/platform/services/telemetry/telemetry_test.go index dce4935d392..52ab021bdad 100644 --- a/server/platform/services/telemetry/telemetry_test.go +++ b/server/platform/services/telemetry/telemetry_test.go @@ -168,7 +168,6 @@ func initializeMocks(cfg *model.Config, cloudLicense bool) (*mocks.ServerIface, func(m *model.Manifest) plugin.API { return pluginsAPIMock }, nil, pluginDir, webappPluginDir, - false, logger, nil) serverIfaceMock.On("GetPluginsEnvironment").Return(pluginEnv, nil) diff --git a/server/plugin/environment.go b/server/plugin/environment.go index 20f612b5abb..2cdcbdd90c5 100644 --- a/server/plugin/environment.go +++ b/server/plugin/environment.go @@ -4,12 +4,10 @@ package plugin import ( - "bytes" "fmt" "hash/fnv" "os" "path/filepath" - "strings" "sync" "time" @@ -59,7 +57,6 @@ type Environment struct { dbDriver Driver pluginDir string webappPluginDir string - patchReactDOM bool prepackagedPlugins []*PrepackagedPlugin prepackagedPluginsLock sync.RWMutex } @@ -69,7 +66,6 @@ func NewEnvironment( dbDriver Driver, pluginDir string, webappPluginDir string, - patchReactDOM bool, logger *mlog.Logger, metrics einterfaces.MetricsInterface, ) (*Environment, error) { @@ -80,7 +76,6 @@ func NewEnvironment( dbDriver: dbDriver, pluginDir: pluginDir, webappPluginDir: webappPluginDir, - patchReactDOM: patchReactDOM, }, nil } @@ -488,17 +483,6 @@ func (env *Environment) UnpackWebappBundle(id string) (*model.Manifest, error) { return nil, errors.Wrapf(err, "unable to read webapp bundle: %v", id) } - if env.patchReactDOM { - newContents, changed := patchReactDOM(sourceBundleFileContents) - if changed { - sourceBundleFileContents = newContents - err = os.WriteFile(sourceBundleFilepath, sourceBundleFileContents, 0644) - if err != nil { - return nil, errors.Wrapf(err, "unable to overwrite webapp bundle: %v", id) - } - } - } - hash := fnv.New64a() if _, err = hash.Write(sourceBundleFileContents); err != nil { return nil, errors.Wrapf(err, "unable to generate hash for webapp bundle: %v", id) @@ -515,52 +499,6 @@ func (env *Environment) UnpackWebappBundle(id string) (*model.Manifest, error) { return manifest, nil } -func patchReactDOM(initialBytes []byte) ([]byte, bool) { - if !bytes.Contains(initialBytes, []byte("react-dom.production.min.js")) { - return initialBytes, false - } - - initial := string(initialBytes) - nameIndex := strings.Index(initial, "react-dom.production.min.js") - - beginning := strings.LastIndex(initial[:nameIndex], "{") - var end int - - argDefBeginning := strings.LastIndex(initial[:beginning], "function") + 9 - argDefEnd := strings.LastIndex(initial[:beginning], ")") - 1 - argsNames := strings.Split(initial[argDefBeginning:argDefEnd], ",") - if len(argsNames) != 3 { - return initialBytes, false - } - - exportsArgName := strings.TrimSpace(argsNames[1]) - - numOpenBraces := 0 - for i, c := range initial[beginning:] { - if end != 0 { - break - } - switch c { - case '}': - numOpenBraces-- - - if numOpenBraces == 0 { - end = beginning + i - } - case '{': - numOpenBraces++ - } - } - - beforePatch := initial[:end] - afterPatch := initial[end:] - - patch := fmt.Sprintf("; Object.assign(%s, window.ReactDOM)", exportsArgName) - - result := fmt.Sprintf("%s%s%s", beforePatch, patch, afterPatch) - return []byte(result), true -} - // HooksForPlugin returns the hooks API for the plugin with the given id. // // Consider using RunMultiPluginHook instead. diff --git a/webapp/channels/src/components/admin_console/admin_definition.jsx b/webapp/channels/src/components/admin_console/admin_definition.jsx index 2ce6a1c4049..5df1eb17f6c 100644 --- a/webapp/channels/src/components/admin_console/admin_definition.jsx +++ b/webapp/channels/src/components/admin_console/admin_definition.jsx @@ -6867,26 +6867,6 @@ const AdminDefinition = { isHidden: it.licensedForFeature('Cloud'), isDisabled: it.not(it.userHasWritePermissionOnResource(RESOURCE_KEYS.EXPERIMENTAL.FEATURES)), }, - { - type: Constants.SettingsTypes.TYPE_BOOL, - key: 'ExperimentalSettings.PatchPluginsReactDOM', - label: t('admin.experimental.patchPluginsReactDOM.title'), - label_default: 'Patch React DOM used by plugins:', - help_text: t('admin.experimental.patchPluginsReactDOM.desc'), - help_text_default: 'When true, client-side plugins will be patched to use the version of React DOM provided by the web app. This should only be enabled if plugins break after upgrading to Mattermost 7.6. The server must be restarted for this setting to take effect. See the Important Upgrade Notes for more information.', - help_text_values: { - link: (msg) => ( - - {msg} - - ), - }, - isHidden: it.licensedForFeature('Cloud'), - isDisabled: it.not(it.userHasWritePermissionOnResource(RESOURCE_KEYS.EXPERIMENTAL.FEATURES)), - }, { type: Constants.SettingsTypes.TYPE_BOOL, key: 'ExperimentalSettings.DisableRefetchingOnBrowserFocus', diff --git a/webapp/channels/src/i18n/en.json b/webapp/channels/src/i18n/en.json index df8ff23378e..c5fda916701 100644 --- a/webapp/channels/src/i18n/en.json +++ b/webapp/channels/src/i18n/en.json @@ -954,8 +954,6 @@ "admin.experimental.linkMetadataTimeoutMilliseconds.desc": "The number of milliseconds to wait for metadata from a third-party link. Used with Post Metadata.", "admin.experimental.linkMetadataTimeoutMilliseconds.example": "E.g.: \"5000\"", "admin.experimental.linkMetadataTimeoutMilliseconds.title": "Link Metadata Timeout:", - "admin.experimental.patchPluginsReactDOM.desc": "When true, client-side plugins will be patched to use the version of React DOM provided by the web app. This should only be enabled if plugins break after upgrading to Mattermost 7.6. The server must be restarted for this setting to take effect. See the Important Upgrade Notes for more information.", - "admin.experimental.patchPluginsReactDOM.title": "Patch React DOM used by plugins:", "admin.experimental.samlSettingsLoginButtonBorderColor.desc": "Specify the color of the SAML login button border for white labeling purposes. Use a hex code with a #-sign before the code. This setting only applies to the mobile apps.", "admin.experimental.samlSettingsLoginButtonBorderColor.title": "SAML login Button Border Color:", "admin.experimental.samlSettingsLoginButtonColor.desc": "Specify the color of the SAML login button for white labeling purposes. Use a hex code with a #-sign before the code. This setting only applies to the mobile apps.", diff --git a/webapp/platform/types/src/config.ts b/webapp/platform/types/src/config.ts index de54b12b147..1573abe7d2d 100644 --- a/webapp/platform/types/src/config.ts +++ b/webapp/platform/types/src/config.ts @@ -729,7 +729,6 @@ export type ExperimentalSettings = { EnableSharedChannels: boolean; EnableRemoteClusterService: boolean; EnableAppBar: boolean; - PatchPluginsReactDOM: boolean; DisableRefetchingOnBrowserFocus: boolean; DelayChannelAutocomplete: boolean; };