summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--api/context.go16
-rw-r--r--api/post.go1
-rw-r--r--model/config.go4
-rw-r--r--utils/config.go6
-rw-r--r--webapp/actions/websocket_actions.jsx2
-rw-r--r--webapp/components/admin_console/configuration_settings.jsx20
-rw-r--r--webapp/components/create_team/components/team_url.jsx2
-rw-r--r--webapp/components/integrations/components/installed_incoming_webhook.jsx2
-rw-r--r--webapp/i18n/en.json3
-rw-r--r--webapp/stores/team_store.jsx28
-rw-r--r--webapp/utils/utils.jsx4
11 files changed, 56 insertions, 32 deletions
diff --git a/api/context.go b/api/context.go
index 08f41aa6d..c0e6bf3b5 100644
--- a/api/context.go
+++ b/api/context.go
@@ -39,6 +39,7 @@ type Context struct {
Err *model.AppError
teamURLValid bool
teamURL string
+ siteURL string
T goi18n.TranslateFunc
Locale string
TeamId string
@@ -141,10 +142,11 @@ func (h handler) ServeHTTP(w http.ResponseWriter, r *http.Request) {
isTokenFromQueryString = true
}
- // if the site url in the config isn't specified, infer if from this request and write it back to the config
- if *utils.Cfg.ServiceSettings.SiteURL == "" {
- *utils.Cfg.ServiceSettings.SiteURL = GetProtocol(r) + "://" + r.Host
- utils.RegenerateClientConfig()
+ if *utils.Cfg.ServiceSettings.SiteURL != "" {
+ c.SetSiteURL(*utils.Cfg.ServiceSettings.SiteURL)
+ } else {
+ protocol := GetProtocol(r)
+ c.SetSiteURL(protocol + "://" + r.Host)
}
w.Header().Set(model.HEADER_REQUEST_ID, c.RequestId)
@@ -439,6 +441,10 @@ func (c *Context) SetTeamURLFromSession() {
}
}
+func (c *Context) SetSiteURL(url string) {
+ c.siteURL = url
+}
+
func (c *Context) GetTeamURLFromTeam(team *model.Team) string {
return c.GetSiteURL() + "/" + team.Name
}
@@ -454,7 +460,7 @@ func (c *Context) GetTeamURL() string {
}
func (c *Context) GetSiteURL() string {
- return *utils.Cfg.ServiceSettings.SiteURL
+ return c.siteURL
}
func IsApiCall(r *http.Request) bool {
diff --git a/api/post.go b/api/post.go
index 0c7654df1..d32d1c6a5 100644
--- a/api/post.go
+++ b/api/post.go
@@ -458,6 +458,7 @@ func handleWebhookEvents(c *Context, post *model.Post, team *model.Team, channel
Err: nil,
teamURLValid: c.teamURLValid,
teamURL: c.teamURL,
+ siteURL: c.siteURL,
T: c.T,
Locale: c.Locale,
TeamId: hook.TeamId,
diff --git a/model/config.go b/model/config.go
index 61d13360c..d13ba19e6 100644
--- a/model/config.go
+++ b/model/config.go
@@ -870,10 +870,6 @@ func (o *Config) IsValid() *AppError {
return NewLocAppError("Config.IsValid", "model.config.is_valid.listen_address.app_error", nil, "")
}
- if len(o.ServiceSettings.ListenAddress) == 0 {
- return NewLocAppError("Config.IsValid", "model.config.is_valid.listen_address.app_error", nil, "")
- }
-
if o.TeamSettings.MaxUsersPerTeam <= 0 {
return NewLocAppError("Config.IsValid", "model.config.is_valid.max_users.app_error", nil, "")
}
diff --git a/utils/config.go b/utils/config.go
index a1a6becd1..6646a341e 100644
--- a/utils/config.go
+++ b/utils/config.go
@@ -186,7 +186,7 @@ func LoadConfig(fileName string) {
Cfg = &config
CfgHash = fmt.Sprintf("%x", md5.Sum([]byte(Cfg.ToJson())))
- RegenerateClientConfig()
+ ClientCfg = getClientConfig(Cfg)
// Actions that need to run every time the config is loaded
if ldapI := einterfaces.GetLdapInterface(); ldapI != nil {
@@ -199,10 +199,6 @@ func LoadConfig(fileName string) {
}
}
-func RegenerateClientConfig() {
- ClientCfg = getClientConfig(Cfg)
-}
-
func getClientConfig(c *model.Config) map[string]string {
props := make(map[string]string)
diff --git a/webapp/actions/websocket_actions.jsx b/webapp/actions/websocket_actions.jsx
index e93b2d25b..9150e4111 100644
--- a/webapp/actions/websocket_actions.jsx
+++ b/webapp/actions/websocket_actions.jsx
@@ -32,7 +32,7 @@ const MAX_WEBSOCKET_FAILS = 7;
export function initialize() {
if (window.WebSocket) {
- let connUrl = window.mm_config.SiteURL;
+ let connUrl = Utils.getSiteURL();
// replace the protocol with a websocket one
if (connUrl.startsWith('https:')) {
diff --git a/webapp/components/admin_console/configuration_settings.jsx b/webapp/components/admin_console/configuration_settings.jsx
index e34167a30..6a07e31cd 100644
--- a/webapp/components/admin_console/configuration_settings.jsx
+++ b/webapp/components/admin_console/configuration_settings.jsx
@@ -28,6 +28,7 @@ export default class ConfigurationSettings extends AdminSettings {
}
getConfigFromState(config) {
+ config.ServiceSettings.SiteURL = this.state.siteURL;
config.ServiceSettings.ListenAddress = this.state.listenAddress;
config.ServiceSettings.WebserverMode = this.state.webserverMode;
@@ -36,6 +37,7 @@ export default class ConfigurationSettings extends AdminSettings {
getStateFromConfig(config) {
return {
+ siteURL: config.ServiceSettings.SiteURL,
listenAddress: config.ServiceSettings.ListenAddress,
webserverMode: config.ServiceSettings.WebserverMode
};
@@ -56,6 +58,24 @@ export default class ConfigurationSettings extends AdminSettings {
return (
<SettingsGroup>
<TextSetting
+ id='siteURL'
+ label={
+ <FormattedMessage
+ id='admin.service.siteURL'
+ defaultMessage='Site URL:'
+ />
+ }
+ placeholder={Utils.localizeMessage('admin.service.siteURLExample', 'Ex "https://mattermost.example.com:1234"')}
+ helpText={
+ <FormattedMessage
+ id='admin.service.siteURLDescription'
+ defaultMessage='The URL, including port number and protocol, from which users will access Mattermost. Leave blank to automatically configure based on incoming traffic.'
+ />
+ }
+ value={this.state.siteURL}
+ onChange={this.handleChange}
+ />
+ <TextSetting
id='listenAddress'
label={
<FormattedMessage
diff --git a/webapp/components/create_team/components/team_url.jsx b/webapp/components/create_team/components/team_url.jsx
index bcbe0a1a1..b6c7d38f3 100644
--- a/webapp/components/create_team/components/team_url.jsx
+++ b/webapp/components/create_team/components/team_url.jsx
@@ -105,7 +105,7 @@ export default class TeamUrl extends React.Component {
nameDivClass += ' has-error';
}
- const title = `${window.mm_config.SiteURL}/`;
+ const title = `${Utils.getSiteURL()}/`;
const urlTooltip = (
<Tooltip id='urlTooltip'>{title}</Tooltip>
);
diff --git a/webapp/components/integrations/components/installed_incoming_webhook.jsx b/webapp/components/integrations/components/installed_incoming_webhook.jsx
index 008000012..965ed2bc9 100644
--- a/webapp/components/integrations/components/installed_incoming_webhook.jsx
+++ b/webapp/components/integrations/components/installed_incoming_webhook.jsx
@@ -97,7 +97,7 @@ export default class InstalledIncomingWebhook extends React.Component {
id='installed_integrations.url'
defaultMessage='URL: {url}'
values={{
- url: window.mm_config.SiteURL + '/hooks/' + incomingWebhook.id
+ url: Utils.getSiteURL() + '/hooks/' + incomingWebhook.id
}}
/>
</span>
diff --git a/webapp/i18n/en.json b/webapp/i18n/en.json
index 1dc2f49d1..478fbf362 100644
--- a/webapp/i18n/en.json
+++ b/webapp/i18n/en.json
@@ -640,6 +640,9 @@
"admin.service.sessionCache": "Session Cache (minutes):",
"admin.service.sessionCacheDesc": "The number of minutes to cache a session in memory.",
"admin.service.sessionDaysEx": "Ex \"30\"",
+ "admin.service.siteURL": "Site URL:",
+ "admin.service.siteURLDescription": "The URL, including port number and protocol, from which users will access Mattermost. Leave blank to automatically configure based on incoming traffic.",
+ "admin.service.siteURLExample": "Ex \"https://mattermost.example.com:1234\"",
"admin.service.ssoSessionDays": "Session length SSO (days):",
"admin.service.ssoSessionDaysDesc": "The number of days from the last time a user entered their credentials to the expiry of the user's session. If the authentication method is SAML or GitLab, the user may automatically be logged back in to Mattermost if they are already logged in to SAML or GitLab. After changing this setting, the setting will take effect after the next time the user enters their credentials.",
"admin.service.testingDescription": "When true, /loadtest slash command is enabled to load test accounts, data and text formatting. Changing this requires a server restart before taking effect.",
diff --git a/webapp/stores/team_store.jsx b/webapp/stores/team_store.jsx
index a482fa3a1..90cb66bb2 100644
--- a/webapp/stores/team_store.jsx
+++ b/webapp/stores/team_store.jsx
@@ -60,13 +60,7 @@ class TeamStoreClass extends EventEmitter {
}
getCurrentId() {
- var team = this.get(this.currentTeamId);
-
- if (team) {
- return team.id;
- }
-
- return null;
+ return this.currentTeamId;
}
getCurrent() {
@@ -80,10 +74,7 @@ class TeamStoreClass extends EventEmitter {
}
getCurrentTeamUrl() {
- if (this.getCurrent()) {
- return window.mm_config.SiteURL + '/' + this.getCurrent().name;
- }
- return '';
+ return this.getTeamUrl(this.currentTeamId);
}
getCurrentTeamRelativeUrl() {
@@ -97,7 +88,10 @@ class TeamStoreClass extends EventEmitter {
const current = this.getCurrent();
if (current) {
- return window.mm_config.SiteURL + '/signup_user_complete/?id=' + current.invite_id;
+ // can't call Utils.getSiteURL here because that introduces a circular dependency
+ const origin = window.mm_config.SiteURL || window.location.origin;
+
+ return origin + '/signup_user_complete/?id=' + current.invite_id;
}
return '';
@@ -105,11 +99,15 @@ class TeamStoreClass extends EventEmitter {
getTeamUrl(id) {
const team = this.get(id);
- if (team) {
- return window.mm_config.SiteURL + '/' + team.name;
+
+ if (!team) {
+ return '';
}
- return '';
+ // can't call Utils.getSiteURL here because that introduces a circular dependency
+ const origin = window.mm_config.SiteURL || window.location.origin;
+
+ return origin + '/' + team.name;
}
saveTeam(team) {
diff --git a/webapp/utils/utils.jsx b/webapp/utils/utils.jsx
index e3db6d827..9731d3ce2 100644
--- a/webapp/utils/utils.jsx
+++ b/webapp/utils/utils.jsx
@@ -1338,3 +1338,7 @@ export function isValidPassword(password) {
return errorMsg;
}
+
+export function getSiteURL() {
+ return global.mm_config.SiteURL || window.location.origin;
+} \ No newline at end of file