From 00096eddf5e8eab80aeaa29ea1a4ce0ba75aeff9 Mon Sep 17 00:00:00 2001 From: Travis Ralston Date: Fri, 22 Feb 2019 20:55:49 -0700 Subject: [PATCH] Add a script to generate a sample config Addresses https://github.com/vector-im/riot-web/issues/8449 --- README.md | 2 +- config.sample.json | 118 ++++++++++++++++++++++---- package.json | 1 + scripts/gen-sample-config.js | 157 +++++++++++++++++++++++++++++++++++ 4 files changed, 261 insertions(+), 17 deletions(-) create mode 100644 scripts/gen-sample-config.js diff --git a/README.md b/README.md index d7c7ba96..993524a0 100644 --- a/README.md +++ b/README.md @@ -116,7 +116,7 @@ config.json You can configure the app by copying `config.sample.json` to `config.json` and customising it: -For a good example, see https://riot.im/develop/config.json. +For a good example of a production config, see https://riot.im/develop/config.json. 1. `default_server_name` sets the default server name to use for authentication. This will trigger Riot to ask diff --git a/config.sample.json b/config.sample.json index 4208438d..3e6c3de3 100644 --- a/config.sample.json +++ b/config.sample.json @@ -1,34 +1,120 @@ { - "default_hs_url": "https://matrix.org", - "default_is_url": "https://vector.im", + "default_server_name": "matrix.org", "disable_custom_urls": false, "disable_guests": false, "disable_login_language_selector": false, "disable_3pid_login": false, "brand": "Riot", + "welcomeUserId": "@riot-bot:matrix.org", + "default_federate": true, + "bug_report_endpoint_url": "https://riot.im/bugreports/submit", "integrations_ui_url": "https://scalar.vector.im/", "integrations_rest_url": "https://scalar.vector.im/api", "integrations_jitsi_widget_url": "https://scalar.vector.im/api/widgets/jitsi.html", - "bug_report_endpoint_url": "https://riot.im/bugreports/submit", - "features": { - "feature_groups": "labs", - "feature_pinning": "labs" - }, - "default_federate": true, + "integrations_widgets_urls": [ + "https://scalar-staging.riot.im/scalar/api", + "https://scalar.vector.im/api" + ], "default_theme": "light", "roomDirectory": { "servers": [ "matrix.org" ] }, - "welcomeUserId": "@riot-bot:matrix.org", - "piwik": { - "url": "https://piwik.riot.im/", - "whitelistedHSUrls": ["https://matrix.org"], - "whitelistedISUrls": ["https://vector.im", "https://matrix.org"], - "siteId": 1 - }, "enable_presence_by_hs_url": { "https://matrix.org": false + }, + "piwik": { + "siteId": 1, + "url": "https://piwik.riot.im", + "whitelistedHSUrls": [ + "https://matrix.org" + ], + "whitelistedISUrls": [ + "https://vector.im", + "https://matrix.org" + ] + }, + "embeddedPages": { + "homeUrl": "home.html", + "welcomeUrl": "welcome.html" + }, + "cross_origin_renderer_url": "https://usercontent.riot.im/v1.html", + "branding": { + "authHeaderLogoUrl": "themes/riot/img/logos/riot-im-logo-black-text.svg", + "welcomeBackgroundUrl": "themes/riot/img/backgrounds/valley.jpg" + }, + "update_base_url": "https://riot.im/download/desktop/update/", + "sync_timeline_limit": 8, + "terms_and_conditions_links": [ + { + "url": "https://matrix.org/docs/guides/code_of_conduct", + "text": "matrix.org code of conduct" + } + ], + "phasedRollOut": { + "feature_pinning": { + "offset": 1550893490769, + "period": 604800000 + }, + "feature_custom_status": { + "offset": 1550893490769, + "period": 604800000 + }, + "feature_room_breadcrumbs": { + "offset": 1550893490769, + "period": 604800000 + }, + "feature_custom_tags": { + "offset": 1550893490769, + "period": 604800000 + }, + "feature_state_counters": { + "offset": 1550893490769, + "period": 604800000 + } + }, + "features": { + "feature_pinning": "labs", + "feature_custom_status": "labs", + "feature_room_breadcrumbs": "labs", + "feature_custom_tags": "labs", + "feature_state_counters": "labs" + }, + "settingDefaults": { + "MessageComposerInput.dontSuggestEmoji": false, + "useCompactLayout": false, + "hideRedactions": false, + "hideJoinLeaves": false, + "hideAvatarChanges": false, + "hideDisplaynameChanges": false, + "hideReadReceipts": false, + "showTwelveHourTimestamps": false, + "alwaysShowTimestamps": false, + "autoplayGifsAndVideos": false, + "alwaysShowEncryptionIcons": true, + "showRoomRecoveryReminder": true, + "enableSyntaxHighlightLanguageDetection": false, + "Pill.shouldHidePillAvatar": false, + "TextualBody.disableBigEmoji": false, + "MessageComposerInput.isRichTextEnabled": false, + "MessageComposer.showFormatting": false, + "dontSendTypingNotifications": false, + "MessageComposerInput.autoReplaceEmoji": false, + "VideoView.flipVideoHorizontally": false, + "TagPanel.disableTagPanel": false, + "webRtcForceTURN": false, + "language": "en", + "analyticsOptIn": false, + "showCookieBar": true, + "autocompleteDelay": 200, + "urlPreviewsEnabled": true, + "roomColor": { + "primary_color": "#a442f4", + "secondary_color": "#cc92fc" + }, + "enableWidgetScreenshots": false, + "promptBeforeInviteUnknownUsers": true, + "showDeveloperTools": false } -} +} \ No newline at end of file diff --git a/package.json b/package.json index 19cc5e6a..122f5456 100644 --- a/package.json +++ b/package.json @@ -30,6 +30,7 @@ "reskindex:watch": "reskindex -h src/header -w", "i18n": "matrix-gen-i18n", "prunei18n": "matrix-prune-i18n", + "gensampleconf": "node scripts/gen-sample-config.js", "build:res": "node scripts/copy-res.js", "build:modernizr": "modernizr -c .modernizr.json -d src/vector/modernizr.js", "build:compile": "npm run reskindex && babel --source-maps -d lib src", diff --git a/scripts/gen-sample-config.js b/scripts/gen-sample-config.js new file mode 100644 index 00000000..bf138d22 --- /dev/null +++ b/scripts/gen-sample-config.js @@ -0,0 +1,157 @@ +/* +Copyright 2019 New Vector Ltd. + +Licensed under the Apache License, Version 2.0 (the "License"); +you may not use this file except in compliance with the License. +You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +See the License for the specific language governing permissions and +limitations under the License. +*/ + +// The sample config is generated as follows: +// 1. Start with SdkConfig's DEFAULTS +// 2. Overwrite with features and Settings defaults +// 3. Overwrite with samples defined here + +const SdkConfig = require("matrix-react-sdk/lib/SdkConfig"); +const fs = require("fs"); + +const SAMPLES = { + default_server_name: "matrix.org", + disable_custom_urls: false, + disable_guests: false, + disable_login_language_selector: false, + disable_3pid_login: false, + brand: "Riot", + welcomeUserId: "@riot-bot:matrix.org", + default_federate: true, + bug_report_endpoint_url: "https://riot.im/bugreports/submit", + integrations_ui_url: "https://scalar.vector.im/", + integrations_rest_url: "https://scalar.vector.im/api", + integrations_jitsi_widget_url: "https://scalar.vector.im/api/widgets/jitsi.html", + integrations_widgets_urls: [ + "https://scalar-staging.riot.im/scalar/api", + "https://scalar.vector.im/api", + ], + default_theme: "light", + roomDirectory: { + servers: [ + "matrix.org", + ], + }, + enable_presence_by_hs_url: { + "https://matrix.org": false, + }, + piwik: { + siteId: 1, + url: "https://piwik.riot.im", + whitelistedHSUrls: ["https://matrix.org"], + whitelistedISUrls: ["https://vector.im", "https://matrix.org"], + }, + embeddedPages: { + homeUrl: "home.html", + welcomeUrl: "welcome.html", + }, + cross_origin_renderer_url: "https://usercontent.riot.im/v1.html", + branding: { + authHeaderLogoUrl: "themes/riot/img/logos/riot-im-logo-black-text.svg", + welcomeBackgroundUrl: "themes/riot/img/backgrounds/valley.jpg", + }, + update_base_url: "https://riot.im/download/desktop/update/", + sync_timeline_limit: 8, + terms_and_conditions_links: [ + { + url: "https://matrix.org/docs/guides/code_of_conduct", + text: "matrix.org code of conduct", + }, + ], +}; + +function parseSettings() { + // This is by far the worst and cleanest way to load the settings config. + // We parse the file (and eval(!!!) it), stripping out lines that will cause + // us issues, like imports, controllers, and language references. If we don't + // strip out imports and such, we'll get all kinds of fun errors because we + // won't have loaded the dependency chain for a web browser, making things like + // the language handler complain. + const contents = fs.readFileSync(require.resolve("matrix-react-sdk/src/settings/Settings")); + const lines = (contents.toString()).split('\n').map(s => s.trim()); + + let foundFirstConst = false; + const rebuiltLines = lines.filter(s => { + // Strip everything up until the first variable definition (because multiline imports are a thing) + if (s.indexOf("const ") === 0) foundFirstConst = true; + if (!foundFirstConst) return false; + + // Filter out anything else that might cause us problems when we eval it + return s.indexOf("controller:") === -1 && s.indexOf("_td(") === -1; + }).map(s => s.indexOf("export const") === 0 ? s.substring("export ".length) : s); + + const scriptBase = rebuiltLines.join('\n'); + + // We wrap it to prevent variable leaking, but this doesn't protect us from random file access, etc. + const wrapper = `(function(){${scriptBase}\nreturn SETTINGS;})();`; + return eval(wrapper); +} + +function generateSettingsConfig() { + const settingDefaults = {}; + const phasedRollOut = {}; + const features = {}; + + const overrides = { + "roomColor": { + "primary_color": "#a442f4", + "secondary_color": "#cc92fc" + } + }; + + const skipSettings = ['theme']; + + const settings = parseSettings(); + for (const settingName of Object.keys(settings)) { + const setting = settings[settingName]; + + if (setting.isFeature) { + phasedRollOut[settingName] = { + offset: new Date().getTime(), + period: 604800000, + }; + + features[settingName] = 'labs'; + + continue; + } + + if (setting.supportedLevels.indexOf('config') === -1) continue; + if (skipSettings.indexOf(settingName) !== -1) continue; + + if (setting.invertedSettingName) { + settingDefaults[setting.invertedSettingName] = !setting.default; + } else { + settingDefaults[settingName] = setting.default; + } + } + + return { + phasedRollOut, + features, + settingDefaults: Object.assign(settingDefaults, overrides), + }; +} + + +const finalSettings = Object.assign({}, + SdkConfig.DEFAULTS, + SAMPLES, + generateSettingsConfig(), +); + +fs.writeFileSync("config.sample.json", JSON.stringify(finalSettings, null, 4)); +console.log("Wrote new sample config");