diff --git a/e2e-tests/playwright/support/server/default_config.ts b/e2e-tests/playwright/support/server/default_config.ts index 4bcfdd5798..211ec381ba 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 95c4fc5cae..e6f5c2a4de 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 2ba65aa5f9..4c9fa41ead 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 0238457662..3dc5e50ee3 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 2c4fb8d229..c6d9d46fbd 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 7bd69d00db..6fe686d5e5 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 6982904d15..e260cdfa90 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 dce4935d39..52ab021bda 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 20f612b5ab..2cdcbdd90c 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 2ce6a1c404..5df1eb17f6 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 df8ff23378..c5fda91670 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 de54b12b14..1573abe7d2 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; };