diff options
author | Jorik Schellekens <joriks@matrix.org> | 2019-08-13 10:15:04 +0100 |
---|---|---|
committer | Jorik Schellekens <joriks@matrix.org> | 2019-08-28 15:59:53 +0100 |
commit | 442da5fbddb5acc243d8d25e97783dc0392005ef (patch) | |
tree | 4fa5f12f7fa9744e0c9e3abe0704fa35050ca091 | |
parent | Accordion stats, keys and delegation. (diff) | |
download | synapse-442da5fbddb5acc243d8d25e97783dc0392005ef.tar.xz |
TLS accordion entry
10 files changed, 151 insertions, 261 deletions
diff --git a/synapse_topology/view/webui/js/components/DelegationOptions.jsx b/synapse_topology/view/webui/js/components/DelegationOptions.jsx index 2799d7661d..ee735c32cc 100644 --- a/synapse_topology/view/webui/js/components/DelegationOptions.jsx +++ b/synapse_topology/view/webui/js/components/DelegationOptions.jsx @@ -62,7 +62,7 @@ export default ({ servername, skip, onClick }) => { </p> <Tabs defaultActiveKey={defaultType} onSelect={k => setType(k)}> - <Tab eventKey={DELEGATION_TYPES.DNS} title="DNS SRV"> + <Tab eventKey={DELEGATION_TYPES.DNS} title={DELEGATION_TYPES.DNS}> <p> You will need access to {servername}'s domain zone DNS records. This method also requires the synapse install's server to provide @@ -73,7 +73,7 @@ export default ({ servername, skip, onClick }) => { again, we'll print the SRV record out for you later.) </p> </Tab> - <Tab eventKey={DELEGATION_TYPES.WELL_KNOWN} title=".well_known"> + <Tab eventKey={DELEGATION_TYPES.WELL_KNOWN} title={DELEGATION_TYPES.WELL_KNOWN}> <p> {servername} provides the url https://{servername}/.well-known/matrix/server which gives diff --git a/synapse_topology/view/webui/js/components/ReverseProxy.jsx b/synapse_topology/view/webui/js/components/ReverseProxy.jsx deleted file mode 100644 index ce8806fabb..0000000000 --- a/synapse_topology/view/webui/js/components/ReverseProxy.jsx +++ /dev/null @@ -1,38 +0,0 @@ -import React, { useState } from 'react'; - -import ContentWrapper from '../containers/ContentWrapper'; - -import { - REVERSE_PROXY_TYPES -} from '../actions/constants' - - -export default ({ onClick }) => { - const defaultValue = REVERSE_PROXY_TYPES.NGINX; - const [reverseProxy, setReverseProxy] = useState(defaultValue); - - const onChange = event => { - console.log("trigered") - console.log(event.target) - setReverseProxy(event.target.value); - } - - return <ContentWrapper> - <h1>Reverse Proxy</h1> - <p> - Please choose the reverse proxy you're using. This is just so we can provide - you with a template later, if you already know how you're going to set yours - up don't worry too much about this. - </p> - <select defaultValue={defaultValue} onChange={onChange} > - <option value={REVERSE_PROXY_TYPES.APACHE}>Apache</option> - <option value={REVERSE_PROXY_TYPES.CADDY}>Caddy</option> - <option value={REVERSE_PROXY_TYPES.HAPROXY}>HAProxy</option> - <option value={REVERSE_PROXY_TYPES.NGINX}>NGiNX</option> - <option value={REVERSE_PROXY_TYPES.OTHER}>Some other Reverse Proxy</option> - </select> - <div> - <button onClick={() => onClick(reverseProxy)}>Safety First</button> - </div> - </ContentWrapper> -} \ No newline at end of file diff --git a/synapse_topology/view/webui/js/components/TLS.jsx b/synapse_topology/view/webui/js/components/TLS.jsx index 4b6898d11d..467bb37bc3 100644 --- a/synapse_topology/view/webui/js/components/TLS.jsx +++ b/synapse_topology/view/webui/js/components/TLS.jsx @@ -1,9 +1,14 @@ -import React from 'react'; +import React, { useState } from 'react'; import style from '../../less/main.less'; -import ButtonDisplay from './ButtonDisplay'; -import ContentWrapper from '../containers/ContentWrapper'; +import Accordion from 'react-bootstrap/Accordion'; +import Card from 'react-bootstrap/Card'; +import Tabs from 'react-bootstrap/Tabs'; +import Tab from 'react-bootstrap/Tab'; + +import { TLS_UI } from '../reducers/ui_constants'; +import { TLS_TYPES, REVERSE_PROXY_TYPES } from '../actions/constants'; const tlsLink = "https://en.wikipedia.org/wiki/Transport_Layer_Security"; const apacheLink = "http://httpd.apache.org/"; @@ -12,66 +17,130 @@ const haproxyLink = "http://www.haproxy.org/"; const nginxLink = "https://www.nginx.com/"; const proxyInfoLink = "https://github.com/matrix-org/synapse/blob/master/docs/reverse_proxy.rst"; -export default ({ onClickACME, onClickTLS, onClickReverseProxy }) => - <ContentWrapper> - <h1>TLS</h1> - <p> - I was going to make a <a target="_blank" href={tlsLink}>TLS</a> joke but it - was making me insecure.. - </p> - <p> - TLS keeps the communication between homeservers secure. To enable TLS you'll - need a TLS cert. You can use ACME, provide your own certs, or let the reverse - proxy handle the TLS certs instead. - </p> - <h3> - ReverseProxy - </h3> - <p> - It is a good idea to use Synapse behind a reverse proxy such as <a target="_blank" href={apacheLink}>Apache</a>, <a target="_blank" href={caddyLink}>Caddy</a>, <a target="_blank" href={haproxyLink}>HAProxy</a>, or <a target="_blank" href={nginxLink}>NGiNX</a>. - </p> - <p> - The main benefit to this is that the reverse proxy can listen on the privilaged port - 443 (which clients like riot expect to connect to) on behalf of synapse. The incoming traffic - is then forwarded to Synapse on a non privilaged port. - <br /> - You need root to listen on ports 0 to 1024 inclusive and - running synapse with root privileges is <b>strongly discouraged</b>. - Reverse proxies are more secure, run with root and pass things on like nobody's business. - <br /> - (Note: you can also have synapse use a non privilaged port - by using one of the delegation methods mentioned earlier.) - </p> - <p> - If you choose to use a Reverse Proxy (good for you) we'll provide you with - configuration templates later. Easy breasy. - </p> - <p> - More information about Reverse Proxies <a target="_blank" href={proxyInfoLink}> in the docs.</a> - </p> - <h3> - ACME - </h3> - <p> - ACME is <strike>a super cool initiative</strike> a protocol that allows TLS - certificates to be requested automagically. Synapse supports ACME by requesting - certs from Let's Encrypt. This is the easiest way to manage your certs because - once you set it up you don't need to manage it. - </p> - <p> - If you wish to use ACME you will need access to port 80 which usually requires - root privileges. Do not run Synapse as root. Use a Reverse Proxy or Authbind - </p> - <h3> - Provide your own TLS certs - </h3> - <p> - If you have your own TLS certs for the domain we'll ask you for the path - to them or you can upload them for synapse to use. - </p> - <ButtonDisplay> - <button onClick={() => onClickACME()}>Use ACME</button> - <button onClick={() => onClickReverseProxy()}>I already/will use a Reverse Proxy with TLS</button> - <button onClick={() => onClickTLS()}>I have a TLS cert</button> - </ButtonDisplay> - </ContentWrapper> \ No newline at end of file +export default ({ testingCertPaths, uploadingCerts, certPathInvalid, certKeyPathInvalid, onClickCertPath, onClickCertUpload, onClickACME, onClickReverseProxy }) => { + const defaultType = TLS_TYPES.REVERSE_PROXY; + + const [type, setType] = useState(defaultType); + + const [certPath, setCertPath] = useState(""); + const [certKeyPath, setCertKeyPath] = useState(""); + const [certFile, setCertFile] = useState(); + const [certKeyFile, setCertKeyFile] = useState(); + + const defaultValue = REVERSE_PROXY_TYPES.NGINX; + const [reverseProxy, setReverseProxy] = useState(defaultValue); + + return <Card> + <Accordion.Toggle as={Card.Header} eventKey={TLS_UI}> + TLS + </Accordion.Toggle> + <Accordion.Collapse eventKey={TLS_UI}> + <Card.Body> + <p> + Synapse uses TLS to ensure communication between homeservers is + secure. To use TLS, you’ll need a TLS certificate. Synapse supports + ACME, providing your own certificates, or reverse proxy handling TLS + certificates. + </p> + <Tabs defaultActiveKey={defaultType} onSelect={k => setType(k)}> + <Tab eventKey={TLS_TYPES.REVERSE_PROXY} title="Reverse Proxy"> + <p> + It is recommended to run Synapse behind a reverse proxy such as <a target="_blank" href={apacheLink}>Apache</a>, <a target="_blank" href={caddyLink}>Caddy</a>, <a target="_blank" href={haproxyLink}>HAProxy</a>, or <a target="_blank" href={nginxLink}>NGiNX</a>. + </p> + <p> + The main benefit to this is that the reverse proxy can listen on + the privileged port 443 (which clients like Riot expect to connect + to) on behalf of synapse. The incoming traffic is then forwarded + to Synapse on a non privileged port. + </p> + <p> + You need root to listen on ports 0 to 1024 inclusive and running + synapse with root privileges is <b>strongly discouraged</b>. + Reverse proxies are more secure, run with root and pass things on + like nobody's business. + </p> + <p> + (Note: you can also have synapse use a non privileged port by + using one of the delegation methods mentioned earlier.) + </p> + <p> + If you choose to use a Reverse Proxy we'll provide you with + configuration templates later. + </p> + <p>More information about Reverse Proxies + <a href="https://github.com/matrix-org/synapse/blob/master/docs/reverse_proxy.rst"> + in the docs</a>. + </p> + <p> + Please choose the reverse proxy you're using. This is just so we can provide + you with a template later, if you already know how you're going to set yours + up don't worry too much about this. + </p> + <select defaultValue={defaultValue} onChange={e => setReverseProxy(e.target.value)} > + <option value={REVERSE_PROXY_TYPES.APACHE}>Apache</option> + <option value={REVERSE_PROXY_TYPES.CADDY}>Caddy</option> + <option value={REVERSE_PROXY_TYPES.HAPROXY}>HAProxy</option> + <option value={REVERSE_PROXY_TYPES.NGINX}>NGiNX</option> + <option value={REVERSE_PROXY_TYPES.OTHER}>Some other Reverse Proxy</option> + </select> + <div> + <button onClick={() => onClickReverseProxy(reverseProxy)}> + I already/will use a Reverse Proxy with TLS + </button> + </div> + </Tab> + <Tab eventKey={TLS_TYPES.ACME} title="ACME"> + <p> + ACME is a protocol that allows TLS certificates to be requested + automagically. Synapse supports ACME by requesting certs from + Let's Encrypt, which is one of the easiest ways to manage your + certificates. + </p> + <p> + If you wish to use ACME you will need access to port 80 which + usually requires root privileges. Do not run Synapse as root. Use + a Reverse Proxy or Authbind + </p> + <button onClick={() => onClickACME()}>Use ACME</button> + </Tab> + <Tab eventKey={TLS_TYPES.TLS} title="Provide your own TLS certs"> + <p> + Specify a path to or upload TLS certs for the domain. + </p> + <p>Please enter {certPathInvalid ? "a valid" : "the"} path to the cert</p> + <input + className={certPathInvalid ? style.invalidInput : undefined} + type="text" + placeholder="/path/to/your/cert.pem" + value={certPath ? certPath : undefined} + onChange={e => setCertPath(e.target.value)} + /> + + <p>Please enter {certKeyPathInvalid ? "a valid" : "the"} path to the cert's key</p> + <input + className={certKeyPathInvalid ? style.invalidInput : undefined} + type="text" + placeholder="/path/to/your/cert/key.tls.key" + value={certKeyPath ? certKeyPath : undefined} + onChange={e => setCertKeyPath(e.target.value)} + /> + + <button + disabled={certPath && certKeyPath ? undefined : true} + onClick={() => onClickCertPath(certPath, certKeyPath)} + >Use TLS Path</button> + + <h3>OR..</h3> + <h1>Upload a TLS cert</h1> + <p>Upload a cert file.</p> + <input type="file" name="cert" onChange={e => setCertFile(e.target.files[0])} /> + <p>Upload the cert's private key file.</p> + <input type="file" name="certkey" onChange={e => setCertKeyFile(e.target.files[0])} /> + <button disabled={certFile && certKeyFile ? undefined : true} onClick={() => onClickCertUpload(certFile, certKeyFile)}>Upload cert</button> + + </Tab> + </Tabs> + </Card.Body> + </Accordion.Collapse> + </Card> +} \ No newline at end of file diff --git a/synapse_topology/view/webui/js/components/TLSCertPath.jsx b/synapse_topology/view/webui/js/components/TLSCertPath.jsx deleted file mode 100644 index c64568a00e..0000000000 --- a/synapse_topology/view/webui/js/components/TLSCertPath.jsx +++ /dev/null @@ -1,61 +0,0 @@ -import React, { useState } from 'react'; - -import style from '../../less/main.less'; - -import ButtonDisplay from './ButtonDisplay'; -import ContentWrapper from '../containers/ContentWrapper'; - - -export default ({ testingCertPaths, uploadingCerts, certPathInvalid, certKeyPathInvalid, onClickCertPath, onClickCertUpload }) => { - const [certPath, setCertPath] = useState(""); - const [certKeyPath, setCertKeyPath] = useState(""); - const [certFile, setCertFile] = useState(); - const [certKeyFile, setCertKeyFile] = useState(); - - if (testingCertPaths) { - return <ContentWrapper><h1>Testing the cert paths.</h1></ContentWrapper> - } else if (uploadingCerts) { - return <ContentWrapper><h1>Uploading Certs</h1></ContentWrapper> - } else { - return <ContentWrapper> - <h1>TLS Path</h1> - <p> - If you have a tls cert on your server you can provide a path to it here. - The cert needs to be a `.pem` file that includes the - full certificate chain including any intermediate certificates. - </p> - - <p>Please enter {certPathInvalid ? "a valid" : "the"} path to the cert</p> - <input - className={certPathInvalid ? style.invalidInput : undefined} - type="text" - placeholder="/path/to/your/cert.pem" - value={certPath ? certPath : undefined} - onChange={e => setCertPath(e.target.value)} - /> - - <p>Please enter {certKeyPathInvalid ? "a valid" : "the"} path to the cert's key</p> - <input - className={certKeyPathInvalid ? style.invalidInput : undefined} - type="text" - placeholder="/path/to/your/cert/key.tls.key" - value={certKeyPath ? certKeyPath : undefined} - onChange={e => setCertKeyPath(e.target.value)} - /> - - <button - disabled={certPath && certKeyPath ? undefined : true} - onClick={() => onClickCertPath(certPath, certKeyPath)} - >Use TLS Path</button> - - <h3>OR..</h3> - <h1>Upload a TLS cert</h1> - <p>Upload a cert file.</p> - <input type="file" name="cert" onChange={e => setCertFile(e.target.files[0])} /> - <p>Upload the cert's private key file.</p> - <input type="file" name="certkey" onChange={e => setCertKeyFile(e.target.files[0])} /> - <button disabled={certFile && certKeyFile ? undefined : true} onClick={() => onClickCertUpload(certFile, certKeyFile)}>Upload cert</button> - - </ContentWrapper > - } -} \ No newline at end of file diff --git a/synapse_topology/view/webui/js/components/UI.jsx b/synapse_topology/view/webui/js/components/UI.jsx index 765871e240..0fc1dc74a9 100644 --- a/synapse_topology/view/webui/js/components/UI.jsx +++ b/synapse_topology/view/webui/js/components/UI.jsx @@ -11,21 +11,15 @@ import { STATS_REPORT_UI, KEY_EXPORT_UI, DELEGATION_OPTIONS_UI, - WELL_KNOWN_UI, - DNS_UI, - WORKER_UI, TLS_UI, - REVERSE_PROXY_UI, PORT_SELECTION_UI, REVERSE_PROXY_TEMPLATE_UI, LOADING_UI, ERROR_UI, - TLS_CERTPATH_UI, DELEGATION_TEMPLATE_UI, DATABASE_UI, } from '../reducers/ui_constants'; -import WalkThrough from './WalkThrough' import Error from './Error'; import Loading from './Loading'; @@ -34,9 +28,7 @@ import ServerName from '../containers/ServerName'; import StatsReporter from '../containers/StatsReporter'; import ExportKeys from '../containers/ExportKeys'; import DelegationOptions from '../containers/DelegationOptions'; -import ReverseProxy from '../containers/ReverseProxy'; import TLS from '../containers/TLS'; -import TLSCertPath from '../containers/TLSCertPath'; import PortSelection from '../containers/PortSelection'; import ReverseProxySampleConfig from '../containers/ReverseProxySampleConfig'; import DelegationSampleConfig from '../containers/DelegationSampleConfig'; @@ -60,12 +52,8 @@ const block_mapping = ui_block => { return <ExportKeys key={ui_block} /> case DELEGATION_OPTIONS_UI: return <DelegationOptions key={ui_block} /> - case REVERSE_PROXY_UI: - return <ReverseProxy key={ui_block} /> case TLS_UI: return <TLS key={ui_block} /> - case TLS_CERTPATH_UI: - return <TLSCertPath key={ui_block} /> case PORT_SELECTION_UI: return <PortSelection key={ui_block} /> case REVERSE_PROXY_TEMPLATE_UI: diff --git a/synapse_topology/view/webui/js/containers/ReverseProxy.js b/synapse_topology/view/webui/js/containers/ReverseProxy.js deleted file mode 100644 index 1adbd0dfd0..0000000000 --- a/synapse_topology/view/webui/js/containers/ReverseProxy.js +++ /dev/null @@ -1,21 +0,0 @@ -import { connect } from 'react-redux'; - -import ReverseProxy from '../components/ReverseProxy'; - -import { advance_ui, set_reverse_proxy } from '../actions'; - -const mapStateToProps = (state, ownProps) => { - -}; - -const mapDispatchToProps = (dispatch) => ({ - onClick: proxy_type => { - dispatch(set_reverse_proxy(proxy_type)); - dispatch(advance_ui()); - } -}); - -export default connect( - null, - mapDispatchToProps -)(ReverseProxy); \ No newline at end of file diff --git a/synapse_topology/view/webui/js/containers/TLS.js b/synapse_topology/view/webui/js/containers/TLS.js index 24f8f2cfe6..6566954db6 100644 --- a/synapse_topology/view/webui/js/containers/TLS.js +++ b/synapse_topology/view/webui/js/containers/TLS.js @@ -2,12 +2,15 @@ import { connect } from 'react-redux'; import TLS from '../components/TLS'; -import { advance_ui, set_tls } from '../actions'; +import { advance_ui, set_tls, set_tls_cert_paths, set_tls_cert_files, set_reverse_proxy } from '../actions'; import { TLS_TYPES } from '../actions/constants'; const mapStateToProps = (state, ownProps) => ({ - + testingCertPaths: state.base_config.testing_cert_paths, + uploadingCertPaths: state.base_config.uploading_certs, + certPathInvalid: state.base_config.cert_path_invalid, + certKeyPathInvalid: state.base_config.cert_key_path_invalid, }); const mapDispathToProps = (dispatch) => ({ @@ -15,13 +18,16 @@ const mapDispathToProps = (dispatch) => ({ dispatch(advance_ui(TLS_TYPES.ACME)); dispatch(set_tls(TLS_TYPES.ACME)); }, - onClickTLS: () => { - dispatch(advance_ui(TLS_TYPES.TLS)); - dispatch(set_tls(TLS_TYPES.TLS)); + onClickReverseProxy: proxy_type => { + dispatch(advance_ui()); + dispatch(set_tls(TLS_TYPES.REVERSE_PROXY)) + dispatch(set_reverse_proxy(proxy_type)) + }, + onClickCertPath: (cert_path, cert_key_path) => { + dispatch(set_tls_cert_paths(cert_path, cert_key_path)); }, - onClickReverseProxy: () => { - dispatch(advance_ui(TLS_TYPES.REVERSE_PROXY)), - dispatch(set_tls(TLS_TYPES.REVERSE_PROXY)) + onClickCertUpload: (tls_cert_file, tls_key_file) => { + dispatch(upload_tls_cert_files(tls_cert_file, tls_key_file)); }, }); diff --git a/synapse_topology/view/webui/js/containers/TLSCertPath.js b/synapse_topology/view/webui/js/containers/TLSCertPath.js deleted file mode 100644 index 612c90e6c6..0000000000 --- a/synapse_topology/view/webui/js/containers/TLSCertPath.js +++ /dev/null @@ -1,26 +0,0 @@ -import { connect } from 'react-redux'; - -import TLSCertPath from '../components/TLSCertPath'; - -import { set_tls_cert_paths, upload_tls_cert_files } from '../actions'; - -const mapStateToProps = state => ({ - testingCertPaths: state.base_config.testing_cert_paths, - uploadingCertPaths: state.base_config.uploading_certs, - certPathInvalid: state.base_config.cert_path_invalid, - certKeyPathInvalid: state.base_config.cert_key_path_invalid, -}); - -const mapDispathToProps = dispatch => ({ - onClickCertPath: (cert_path, cert_key_path) => { - dispatch(set_tls_cert_paths(cert_path, cert_key_path)); - }, - onClickCertUpload: (tls_cert_file, tls_key_file) => { - dispatch(upload_tls_cert_files(tls_cert_file, tls_key_file)); - }, -}); - -export default connect( - mapStateToProps, - mapDispathToProps -)(TLSCertPath) \ No newline at end of file diff --git a/synapse_topology/view/webui/js/reducers/setup-ui-reducer.js b/synapse_topology/view/webui/js/reducers/setup-ui-reducer.js index fb967f1b4c..cc4fffdce8 100644 --- a/synapse_topology/view/webui/js/reducers/setup-ui-reducer.js +++ b/synapse_topology/view/webui/js/reducers/setup-ui-reducer.js @@ -6,15 +6,9 @@ import { STATS_REPORT_UI, KEY_EXPORT_UI, DELEGATION_OPTIONS_UI, - DELEGATION_SERVER_NAME_UI, - WELL_KNOWN_UI, - DNS_UI, TLS_UI, - REVERSE_PROXY_UI, PORT_SELECTION_UI, REVERSE_PROXY_TEMPLATE_UI, - TLS_CERTPATH_UI, - DELEGATION_PORT_SELECTION_UI, DELEGATION_TEMPLATE_UI, DATABASE_UI, } from './ui_constants'; @@ -77,19 +71,6 @@ const forward_mapping = (current_ui, action, base_config) => { case DELEGATION_OPTIONS_UI: return TLS_UI; case TLS_UI: - switch (action.option) { - case TLS_TYPES.ACME: - return PORT_SELECTION_UI; - case TLS_TYPES.TLS: - return TLS_CERTPATH_UI; - case TLS_TYPES.NONE: - return PORT_SELECTION_UI; - case TLS_TYPES.REVERSE_PROXY: - return REVERSE_PROXY_UI; - } - case REVERSE_PROXY_UI: - return PORT_SELECTION_UI; - case TLS_CERTPATH_UI: return PORT_SELECTION_UI; case PORT_SELECTION_UI: return base_config.tls == TLS_TYPES.REVERSE_PROXY ? @@ -103,8 +84,6 @@ const forward_mapping = (current_ui, action, base_config) => { DATABASE_UI; case DELEGATION_TEMPLATE_UI: return DATABASE_UI; - case WELL_KNOWN_UI: - case DNS_UI: default: return SETUP_INTRO_UI; } diff --git a/synapse_topology/view/webui/js/reducers/ui_constants.js b/synapse_topology/view/webui/js/reducers/ui_constants.js index 1b71fc0118..305d184d7a 100644 --- a/synapse_topology/view/webui/js/reducers/ui_constants.js +++ b/synapse_topology/view/webui/js/reducers/ui_constants.js @@ -4,13 +4,7 @@ export const SERVER_NAME_UI = "server_name_ui"; export const STATS_REPORT_UI = "stats_report_ui"; export const KEY_EXPORT_UI = "key_export_ui"; export const DELEGATION_OPTIONS_UI = "delegation_options_ui"; -export const DELEGATION_SERVER_NAME_UI = "delegation_server_name_ui"; -export const DELEGATION_PORT_SELECTION_UI = "delegation_port_selection_ui"; -export const WELL_KNOWN_UI = "well_known_ui"; -export const DNS_UI = "dns_ui"; export const TLS_UI = "tls_ui"; -export const TLS_CERTPATH_UI = "tls_certpath_ui"; -export const REVERSE_PROXY_UI = "reverse_proxy_ui"; export const PORT_SELECTION_UI = "port_selection_ui"; export const REVERSE_PROXY_TEMPLATE_UI = "reverse_proxy_tamplate_ui"; export const DELEGATION_TEMPLATE_UI = "delegation_tamplate_ui"; |