PLT-3408 Add SiteURL to config.json (#3692)
* PLT-3408 Changed serverside code to get the service's URL from config.json * PLT-3408 Changed most clientside code to use the SiteURL config setting instead of window.location * PLT-3408 Changed default SiteURL to be autodetected
Этот коммит содержится в:
коммит произвёл
GitHub
родитель
e67bbcb0ae
Коммит
c4a3118e9f
@@ -39,7 +39,6 @@ type Context struct {
|
|||||||
Err *model.AppError
|
Err *model.AppError
|
||||||
teamURLValid bool
|
teamURLValid bool
|
||||||
teamURL string
|
teamURL string
|
||||||
siteURL string
|
|
||||||
T goi18n.TranslateFunc
|
T goi18n.TranslateFunc
|
||||||
Locale string
|
Locale string
|
||||||
TeamId string
|
TeamId string
|
||||||
@@ -139,8 +138,11 @@ func (h handler) ServeHTTP(w http.ResponseWriter, r *http.Request) {
|
|||||||
isTokenFromQueryString = true
|
isTokenFromQueryString = true
|
||||||
}
|
}
|
||||||
|
|
||||||
protocol := GetProtocol(r)
|
// if the site url in the config isn't specified, infer if from this request and write it back to the config
|
||||||
c.SetSiteURL(protocol + "://" + r.Host)
|
if *utils.Cfg.ServiceSettings.SiteURL == "" {
|
||||||
|
*utils.Cfg.ServiceSettings.SiteURL = GetProtocol(r) + "://" + r.Host
|
||||||
|
utils.RegenerateClientConfig()
|
||||||
|
}
|
||||||
|
|
||||||
w.Header().Set(model.HEADER_REQUEST_ID, c.RequestId)
|
w.Header().Set(model.HEADER_REQUEST_ID, c.RequestId)
|
||||||
w.Header().Set(model.HEADER_VERSION_ID, fmt.Sprintf("%v.%v", model.CurrentVersion, utils.CfgLastModified))
|
w.Header().Set(model.HEADER_VERSION_ID, fmt.Sprintf("%v.%v", model.CurrentVersion, utils.CfgLastModified))
|
||||||
@@ -180,7 +182,7 @@ func (h handler) ServeHTTP(w http.ResponseWriter, r *http.Request) {
|
|||||||
c.Path = r.URL.Path
|
c.Path = r.URL.Path
|
||||||
} else {
|
} else {
|
||||||
splitURL := strings.Split(r.URL.Path, "/")
|
splitURL := strings.Split(r.URL.Path, "/")
|
||||||
c.setTeamURL(protocol+"://"+r.Host+"/"+splitURL[1], true)
|
c.setTeamURL(c.GetSiteURL()+"/"+splitURL[1], true)
|
||||||
c.Path = "/" + strings.Join(splitURL[2:], "/")
|
c.Path = "/" + strings.Join(splitURL[2:], "/")
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -431,10 +433,6 @@ func (c *Context) SetTeamURLFromSession() {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
func (c *Context) SetSiteURL(url string) {
|
|
||||||
c.siteURL = url
|
|
||||||
}
|
|
||||||
|
|
||||||
func (c *Context) GetTeamURLFromTeam(team *model.Team) string {
|
func (c *Context) GetTeamURLFromTeam(team *model.Team) string {
|
||||||
return c.GetSiteURL() + "/" + team.Name
|
return c.GetSiteURL() + "/" + team.Name
|
||||||
}
|
}
|
||||||
@@ -450,7 +448,7 @@ func (c *Context) GetTeamURL() string {
|
|||||||
}
|
}
|
||||||
|
|
||||||
func (c *Context) GetSiteURL() string {
|
func (c *Context) GetSiteURL() string {
|
||||||
return c.siteURL
|
return *utils.Cfg.ServiceSettings.SiteURL
|
||||||
}
|
}
|
||||||
|
|
||||||
func IsApiCall(r *http.Request) bool {
|
func IsApiCall(r *http.Request) bool {
|
||||||
|
|||||||
@@ -457,7 +457,6 @@ func handleWebhookEvents(c *Context, post *model.Post, team *model.Team, channel
|
|||||||
Err: nil,
|
Err: nil,
|
||||||
teamURLValid: c.teamURLValid,
|
teamURLValid: c.teamURLValid,
|
||||||
teamURL: c.teamURL,
|
teamURL: c.teamURL,
|
||||||
siteURL: c.siteURL,
|
|
||||||
T: c.T,
|
T: c.T,
|
||||||
Locale: c.Locale,
|
Locale: c.Locale,
|
||||||
TeamId: hook.TeamId,
|
TeamId: hook.TeamId,
|
||||||
|
|||||||
@@ -1,5 +1,6 @@
|
|||||||
{
|
{
|
||||||
"ServiceSettings": {
|
"ServiceSettings": {
|
||||||
|
"SiteURL": "",
|
||||||
"ListenAddress": ":8065",
|
"ListenAddress": ":8065",
|
||||||
"MaximumLoginAttempts": 10,
|
"MaximumLoginAttempts": 10,
|
||||||
"SegmentDeveloperKey": "",
|
"SegmentDeveloperKey": "",
|
||||||
|
|||||||
@@ -2815,6 +2815,10 @@
|
|||||||
"id": "model.config.is_valid.saml_username_attribute.app_error",
|
"id": "model.config.is_valid.saml_username_attribute.app_error",
|
||||||
"translation": "Invalid Username attribute. Must be set."
|
"translation": "Invalid Username attribute. Must be set."
|
||||||
},
|
},
|
||||||
|
{
|
||||||
|
"id": "model.config.is_valid.site_url.app_error",
|
||||||
|
"translation": "Site URL must be a valid URL and start with http:// or https://"
|
||||||
|
},
|
||||||
{
|
{
|
||||||
"id": "model.config.is_valid.sitename_length.app_error",
|
"id": "model.config.is_valid.sitename_length.app_error",
|
||||||
"translation": "Site name must be less than or equal to {{.MaxLength}} characters."
|
"translation": "Site name must be less than or equal to {{.MaxLength}} characters."
|
||||||
|
|||||||
@@ -70,7 +70,6 @@ var flagEmail string
|
|||||||
var flagPassword string
|
var flagPassword string
|
||||||
var flagTeamName string
|
var flagTeamName string
|
||||||
var flagChannelName string
|
var flagChannelName string
|
||||||
var flagSiteURL string
|
|
||||||
var flagConfirmBackup string
|
var flagConfirmBackup string
|
||||||
var flagRole string
|
var flagRole string
|
||||||
var flagRunCmds bool
|
var flagRunCmds bool
|
||||||
@@ -290,7 +289,6 @@ func parseCmds() {
|
|||||||
flag.StringVar(&flagPassword, "password", "", "")
|
flag.StringVar(&flagPassword, "password", "", "")
|
||||||
flag.StringVar(&flagTeamName, "team_name", "", "")
|
flag.StringVar(&flagTeamName, "team_name", "", "")
|
||||||
flag.StringVar(&flagChannelName, "channel_name", "", "")
|
flag.StringVar(&flagChannelName, "channel_name", "", "")
|
||||||
flag.StringVar(&flagSiteURL, "site_url", "", "")
|
|
||||||
flag.StringVar(&flagConfirmBackup, "confirm_backup", "", "")
|
flag.StringVar(&flagConfirmBackup, "confirm_backup", "", "")
|
||||||
flag.StringVar(&flagFromAuth, "from_auth", "", "")
|
flag.StringVar(&flagFromAuth, "from_auth", "", "")
|
||||||
flag.StringVar(&flagToAuth, "to_auth", "", "")
|
flag.StringVar(&flagToAuth, "to_auth", "", "")
|
||||||
@@ -863,16 +861,8 @@ func cmdInviteUser() {
|
|||||||
os.Exit(1)
|
os.Exit(1)
|
||||||
}
|
}
|
||||||
|
|
||||||
if len(flagSiteURL) == 0 {
|
if len(*utils.Cfg.ServiceSettings.SiteURL) == 0 {
|
||||||
fmt.Fprintln(os.Stderr, "flag needs an argument: -site_url")
|
fmt.Fprintln(os.Stderr, "SiteURL must be specified in config.json")
|
||||||
flag.Usage()
|
|
||||||
os.Exit(1)
|
|
||||||
}
|
|
||||||
|
|
||||||
// basic validation of the URL format
|
|
||||||
if _, err := url.ParseRequestURI(flagSiteURL); err != nil {
|
|
||||||
fmt.Fprintln(os.Stderr, "-site_url flag is invalid. It should look like http://example.com")
|
|
||||||
flag.Usage()
|
|
||||||
os.Exit(1)
|
os.Exit(1)
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -894,7 +884,6 @@ func cmdInviteUser() {
|
|||||||
|
|
||||||
invites := []string{flagEmail}
|
invites := []string{flagEmail}
|
||||||
c := getMockContext()
|
c := getMockContext()
|
||||||
c.SetSiteURL(strings.TrimSuffix(flagSiteURL, "/"))
|
|
||||||
api.InviteMembers(c, team, user, invites)
|
api.InviteMembers(c, team, user, invites)
|
||||||
|
|
||||||
os.Exit(0)
|
os.Exit(0)
|
||||||
@@ -1590,8 +1579,6 @@ FLAGS:
|
|||||||
|
|
||||||
-team_name="name" The team name used in other commands
|
-team_name="name" The team name used in other commands
|
||||||
|
|
||||||
-site_url="url" The site URL used in other commands
|
|
||||||
|
|
||||||
-role="system_admin" The role used in other commands
|
-role="system_admin" The role used in other commands
|
||||||
valid values are
|
valid values are
|
||||||
"" - The empty role is basic user
|
"" - The empty role is basic user
|
||||||
@@ -1611,9 +1598,9 @@ COMMANDS:
|
|||||||
platform -create_user -team_name="name" -email="user@example.com" -password="mypassword" -username="user"
|
platform -create_user -team_name="name" -email="user@example.com" -password="mypassword" -username="user"
|
||||||
|
|
||||||
-invite_user Invites a user to a team by email. It requires the -team_name
|
-invite_user Invites a user to a team by email. It requires the -team_name
|
||||||
, -email and -site_url flags.
|
and -email flags.
|
||||||
Example:
|
Example:
|
||||||
platform -invite_user -team_name="name" -email="user@example.com" -site_url="https://mattermost.example.com"
|
platform -invite_user -team_name="name" -email="user@example.com"
|
||||||
|
|
||||||
-leave_team Removes a user from a team. It requires the -team_name
|
-leave_team Removes a user from a team. It requires the -team_name
|
||||||
and -email.
|
and -email.
|
||||||
|
|||||||
@@ -6,6 +6,7 @@ package model
|
|||||||
import (
|
import (
|
||||||
"encoding/json"
|
"encoding/json"
|
||||||
"io"
|
"io"
|
||||||
|
"net/url"
|
||||||
)
|
)
|
||||||
|
|
||||||
const (
|
const (
|
||||||
@@ -50,6 +51,7 @@ const (
|
|||||||
)
|
)
|
||||||
|
|
||||||
type ServiceSettings struct {
|
type ServiceSettings struct {
|
||||||
|
SiteURL *string
|
||||||
ListenAddress string
|
ListenAddress string
|
||||||
MaximumLoginAttempts int
|
MaximumLoginAttempts int
|
||||||
SegmentDeveloperKey string
|
SegmentDeveloperKey string
|
||||||
@@ -363,6 +365,11 @@ func (o *Config) SetDefaults() {
|
|||||||
o.EmailSettings.PasswordResetSalt = NewRandomString(32)
|
o.EmailSettings.PasswordResetSalt = NewRandomString(32)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if o.ServiceSettings.SiteURL == nil {
|
||||||
|
o.ServiceSettings.SiteURL = new(string)
|
||||||
|
*o.ServiceSettings.SiteURL = ""
|
||||||
|
}
|
||||||
|
|
||||||
if o.ServiceSettings.EnableDeveloper == nil {
|
if o.ServiceSettings.EnableDeveloper == nil {
|
||||||
o.ServiceSettings.EnableDeveloper = new(bool)
|
o.ServiceSettings.EnableDeveloper = new(bool)
|
||||||
*o.ServiceSettings.EnableDeveloper = false
|
*o.ServiceSettings.EnableDeveloper = false
|
||||||
@@ -832,6 +839,16 @@ func (o *Config) IsValid() *AppError {
|
|||||||
return NewLocAppError("Config.IsValid", "model.config.is_valid.login_attempts.app_error", nil, "")
|
return NewLocAppError("Config.IsValid", "model.config.is_valid.login_attempts.app_error", nil, "")
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if len(*o.ServiceSettings.SiteURL) != 0 {
|
||||||
|
if _, err := url.ParseRequestURI(*o.ServiceSettings.SiteURL); err != nil {
|
||||||
|
return NewLocAppError("Config.IsValid", "model.config.is_valid.site_url.app_error", nil, "")
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if len(o.ServiceSettings.ListenAddress) == 0 {
|
||||||
|
return NewLocAppError("Config.IsValid", "model.config.is_valid.listen_address.app_error", nil, "")
|
||||||
|
}
|
||||||
|
|
||||||
if len(o.ServiceSettings.ListenAddress) == 0 {
|
if len(o.ServiceSettings.ListenAddress) == 0 {
|
||||||
return NewLocAppError("Config.IsValid", "model.config.is_valid.listen_address.app_error", nil, "")
|
return NewLocAppError("Config.IsValid", "model.config.is_valid.listen_address.app_error", nil, "")
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -185,7 +185,7 @@ func LoadConfig(fileName string) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
Cfg = &config
|
Cfg = &config
|
||||||
ClientCfg = getClientConfig(Cfg)
|
RegenerateClientConfig()
|
||||||
|
|
||||||
// Actions that need to run every time the config is loaded
|
// Actions that need to run every time the config is loaded
|
||||||
if ldapI := einterfaces.GetLdapInterface(); ldapI != nil {
|
if ldapI := einterfaces.GetLdapInterface(); ldapI != nil {
|
||||||
@@ -198,6 +198,10 @@ func LoadConfig(fileName string) {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func RegenerateClientConfig() {
|
||||||
|
ClientCfg = getClientConfig(Cfg)
|
||||||
|
}
|
||||||
|
|
||||||
func getClientConfig(c *model.Config) map[string]string {
|
func getClientConfig(c *model.Config) map[string]string {
|
||||||
props := make(map[string]string)
|
props := make(map[string]string)
|
||||||
|
|
||||||
@@ -208,6 +212,7 @@ func getClientConfig(c *model.Config) map[string]string {
|
|||||||
props["BuildHashEnterprise"] = model.BuildHashEnterprise
|
props["BuildHashEnterprise"] = model.BuildHashEnterprise
|
||||||
props["BuildEnterpriseReady"] = model.BuildEnterpriseReady
|
props["BuildEnterpriseReady"] = model.BuildEnterpriseReady
|
||||||
|
|
||||||
|
props["SiteURL"] = *c.ServiceSettings.SiteURL
|
||||||
props["SiteName"] = c.TeamSettings.SiteName
|
props["SiteName"] = c.TeamSettings.SiteName
|
||||||
props["EnableTeamCreation"] = strconv.FormatBool(c.TeamSettings.EnableTeamCreation)
|
props["EnableTeamCreation"] = strconv.FormatBool(c.TeamSettings.EnableTeamCreation)
|
||||||
props["EnableUserCreation"] = strconv.FormatBool(c.TeamSettings.EnableUserCreation)
|
props["EnableUserCreation"] = strconv.FormatBool(c.TeamSettings.EnableUserCreation)
|
||||||
|
|||||||
@@ -32,12 +32,26 @@ const MAX_WEBSOCKET_FAILS = 7;
|
|||||||
|
|
||||||
export function initialize() {
|
export function initialize() {
|
||||||
if (window.WebSocket) {
|
if (window.WebSocket) {
|
||||||
let protocol = 'ws://';
|
let connUrl = window.mm_config.SiteURL;
|
||||||
if (window.location.protocol === 'https:') {
|
|
||||||
protocol = 'wss://';
|
// replace the protocol with a websocket one
|
||||||
|
if (connUrl.startsWith('https:')) {
|
||||||
|
connUrl = connUrl.replace(/^https:/, 'wss:');
|
||||||
|
} else {
|
||||||
|
connUrl = connUrl.replace(/^http:/, 'ws:');
|
||||||
}
|
}
|
||||||
|
|
||||||
const connUrl = protocol + location.host + ((/:\d+/).test(location.host) ? '' : Utils.getWebsocketPort(protocol)) + Client.getUsersRoute() + '/websocket';
|
// append a port number if one isn't already specified
|
||||||
|
if (!(/:\d+$/).test(connUrl)) {
|
||||||
|
if (connUrl.startsWith('wss:')) {
|
||||||
|
connUrl += ':' + global.window.mm_config.WebsocketSecurePort;
|
||||||
|
} else {
|
||||||
|
connUrl += ':' + global.window.mm_config.WebsocketPort;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// append the websocket api path
|
||||||
|
connUrl += Client.getUsersRoute() + '/websocket';
|
||||||
|
|
||||||
WebSocketClient.setEventCallback(handleEvent);
|
WebSocketClient.setEventCallback(handleEvent);
|
||||||
WebSocketClient.setReconnectCallback(handleReconnect);
|
WebSocketClient.setReconnectCallback(handleReconnect);
|
||||||
|
|||||||
@@ -4,6 +4,7 @@
|
|||||||
import ReactDOM from 'react-dom';
|
import ReactDOM from 'react-dom';
|
||||||
import Constants from 'utils/constants.jsx';
|
import Constants from 'utils/constants.jsx';
|
||||||
import {Modal, Tooltip, OverlayTrigger} from 'react-bootstrap';
|
import {Modal, Tooltip, OverlayTrigger} from 'react-bootstrap';
|
||||||
|
import TeamStore from 'stores/team_store.jsx';
|
||||||
import * as Utils from 'utils/utils.jsx';
|
import * as Utils from 'utils/utils.jsx';
|
||||||
|
|
||||||
import {FormattedMessage} from 'react-intl';
|
import {FormattedMessage} from 'react-intl';
|
||||||
@@ -130,8 +131,8 @@ export default class ChangeUrlModal extends React.Component {
|
|||||||
serverError = <div className='form-group has-error'><p className='input__help error'>{this.props.serverError}</p></div>;
|
serverError = <div className='form-group has-error'><p className='input__help error'>{this.props.serverError}</p></div>;
|
||||||
}
|
}
|
||||||
|
|
||||||
const fullTeamUrl = Utils.getTeamURLFromAddressBar();
|
const fullTeamUrl = TeamStore.getCurrentTeamUrl();
|
||||||
const teamURL = Utils.getShortenedTeamURL();
|
const teamURL = Utils.getShortenedTeamURL(TeamStore.getCurrentTeamUrl());
|
||||||
const urlTooltip = (
|
const urlTooltip = (
|
||||||
<Tooltip id='urlTooltip'>{fullTeamUrl}</Tooltip>
|
<Tooltip id='urlTooltip'>{fullTeamUrl}</Tooltip>
|
||||||
);
|
);
|
||||||
|
|||||||
@@ -123,7 +123,7 @@ export default class ChannelHeader extends React.Component {
|
|||||||
});
|
});
|
||||||
|
|
||||||
const townsquare = ChannelStore.getByName('town-square');
|
const townsquare = ChannelStore.getByName('town-square');
|
||||||
browserHistory.push(Utils.getTeamURLNoOriginFromAddressBar() + '/channels/' + townsquare.name);
|
browserHistory.push(TeamStore.getCurrentTeamRelativeUrl() + '/channels/' + townsquare.name);
|
||||||
},
|
},
|
||||||
(err) => {
|
(err) => {
|
||||||
AsyncClient.dispatchError(err, 'handleLeave');
|
AsyncClient.dispatchError(err, 'handleLeave');
|
||||||
|
|||||||
@@ -5,6 +5,7 @@ import * as Utils from 'utils/utils.jsx';
|
|||||||
|
|
||||||
import {FormattedMessage} from 'react-intl';
|
import {FormattedMessage} from 'react-intl';
|
||||||
import {Modal} from 'react-bootstrap';
|
import {Modal} from 'react-bootstrap';
|
||||||
|
import TeamStore from 'stores/team_store.jsx';
|
||||||
import * as TextFormatting from 'utils/text_formatting.jsx';
|
import * as TextFormatting from 'utils/text_formatting.jsx';
|
||||||
|
|
||||||
import React from 'react';
|
import React from 'react';
|
||||||
@@ -44,7 +45,7 @@ export default class ChannelInfoModal extends React.Component {
|
|||||||
channelIcon = (<span className='fa fa-lock'/>);
|
channelIcon = (<span className='fa fa-lock'/>);
|
||||||
}
|
}
|
||||||
|
|
||||||
const channelURL = Utils.getTeamURLFromAddressBar() + '/channels/' + channel.name;
|
const channelURL = TeamStore.getCurrentTeamUrl() + '/channels/' + channel.name;
|
||||||
|
|
||||||
let channelPurpose = null;
|
let channelPurpose = null;
|
||||||
if (channel.purpose) {
|
if (channel.purpose) {
|
||||||
|
|||||||
@@ -105,7 +105,7 @@ export default class TeamUrl extends React.Component {
|
|||||||
nameDivClass += ' has-error';
|
nameDivClass += ' has-error';
|
||||||
}
|
}
|
||||||
|
|
||||||
const title = `${Utils.getWindowLocationOrigin()}/`;
|
const title = `${window.mm_config.SiteURL}/`;
|
||||||
const urlTooltip = (
|
const urlTooltip = (
|
||||||
<Tooltip id='urlTooltip'>{title}</Tooltip>
|
<Tooltip id='urlTooltip'>{title}</Tooltip>
|
||||||
);
|
);
|
||||||
|
|||||||
@@ -102,7 +102,7 @@ class FileAttachment extends React.Component {
|
|||||||
getFileInfoFromName(name) {
|
getFileInfoFromName(name) {
|
||||||
var fileInfo = utils.splitFileLocation(name);
|
var fileInfo = utils.splitFileLocation(name);
|
||||||
|
|
||||||
fileInfo.path = utils.getWindowLocationOrigin() + Client.getFilesRoute() + '/get' + fileInfo.path;
|
fileInfo.path = Client.getFilesRoute() + '/get' + fileInfo.path;
|
||||||
|
|
||||||
return fileInfo;
|
return fileInfo;
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -97,7 +97,7 @@ export default class InstalledIncomingWebhook extends React.Component {
|
|||||||
id='installed_integrations.url'
|
id='installed_integrations.url'
|
||||||
defaultMessage='URL: {url}'
|
defaultMessage='URL: {url}'
|
||||||
values={{
|
values={{
|
||||||
url: Utils.getWindowLocationOrigin() + '/hooks/' + incomingWebhook.id
|
url: window.mm_config.SiteURL + '/hooks/' + incomingWebhook.id
|
||||||
}}
|
}}
|
||||||
/>
|
/>
|
||||||
</span>
|
</span>
|
||||||
|
|||||||
@@ -277,7 +277,7 @@ export default class LoginController extends React.Component {
|
|||||||
}
|
}
|
||||||
|
|
||||||
createLoginOptions() {
|
createLoginOptions() {
|
||||||
const extraParam = Utils.getUrlParameter('extra');
|
const extraParam = this.props.location.query.extra;
|
||||||
let extraBox = '';
|
let extraBox = '';
|
||||||
if (extraParam) {
|
if (extraParam) {
|
||||||
if (extraParam === Constants.SIGNIN_CHANGE) {
|
if (extraParam === Constants.SIGNIN_CHANGE) {
|
||||||
|
|||||||
@@ -74,7 +74,7 @@ export default class MoreChannels extends React.Component {
|
|||||||
channel,
|
channel,
|
||||||
() => {
|
() => {
|
||||||
$(ReactDOM.findDOMNode(this.refs.modal)).modal('hide');
|
$(ReactDOM.findDOMNode(this.refs.modal)).modal('hide');
|
||||||
browserHistory.push(Utils.getTeamURLNoOriginFromAddressBar() + '/channels/' + channel.name);
|
browserHistory.push(TeamStore.getCurrentTeamRelativeUrl() + '/channels/' + channel.name);
|
||||||
this.setState({joiningChannel: ''});
|
this.setState({joiningChannel: ''});
|
||||||
},
|
},
|
||||||
(err) => {
|
(err) => {
|
||||||
|
|||||||
@@ -87,7 +87,7 @@ export default class MoreDirectChannels extends React.Component {
|
|||||||
Utils.openDirectChannelToUser(
|
Utils.openDirectChannelToUser(
|
||||||
teammate,
|
teammate,
|
||||||
(channel) => {
|
(channel) => {
|
||||||
browserHistory.push(Utils.getTeamURLNoOriginFromAddressBar() + '/channels/' + channel.name);
|
browserHistory.push(TeamStore.getCurrentTeamUrl() + '/channels/' + channel.name);
|
||||||
this.setState({loadingDMChannel: -1});
|
this.setState({loadingDMChannel: -1});
|
||||||
this.handleHide();
|
this.handleHide();
|
||||||
},
|
},
|
||||||
|
|||||||
@@ -88,7 +88,7 @@ export default class NavbarDropdown extends React.Component {
|
|||||||
|
|
||||||
return (
|
return (
|
||||||
<li>
|
<li>
|
||||||
<Link to={'/' + Utils.getTeamNameFromUrl() + '/emoji'}>
|
<Link to={'/' + this.props.teamName + '/emoji'}>
|
||||||
<FormattedMessage
|
<FormattedMessage
|
||||||
id='navbar_dropdown.emoji'
|
id='navbar_dropdown.emoji'
|
||||||
defaultMessage='Custom Emoji'
|
defaultMessage='Custom Emoji'
|
||||||
@@ -207,7 +207,7 @@ export default class NavbarDropdown extends React.Component {
|
|||||||
if (integrationsEnabled && (isAdmin || window.mm_config.EnableOnlyAdminIntegrations !== 'true')) {
|
if (integrationsEnabled && (isAdmin || window.mm_config.EnableOnlyAdminIntegrations !== 'true')) {
|
||||||
integrationsLink = (
|
integrationsLink = (
|
||||||
<li>
|
<li>
|
||||||
<Link to={'/' + Utils.getTeamNameFromUrl() + '/integrations'}>
|
<Link to={'/' + this.props.teamName + '/integrations'}>
|
||||||
<FormattedMessage
|
<FormattedMessage
|
||||||
id='navbar_dropdown.integrations'
|
id='navbar_dropdown.integrations'
|
||||||
defaultMessage='Integrations'
|
defaultMessage='Integrations'
|
||||||
|
|||||||
@@ -73,7 +73,7 @@ export default class NeedsTeam extends React.Component {
|
|||||||
// Go to tutorial if we are first arriving
|
// Go to tutorial if we are first arriving
|
||||||
const tutorialStep = PreferenceStore.getInt(Preferences.TUTORIAL_STEP, UserStore.getCurrentId(), 999);
|
const tutorialStep = PreferenceStore.getInt(Preferences.TUTORIAL_STEP, UserStore.getCurrentId(), 999);
|
||||||
if (tutorialStep <= TutorialSteps.INTRO_SCREENS) {
|
if (tutorialStep <= TutorialSteps.INTRO_SCREENS) {
|
||||||
browserHistory.push(Utils.getTeamURLNoOriginFromAddressBar() + '/tutorial');
|
browserHistory.push(TeamStore.getCurrentTeamRelativeUrl() + '/tutorial');
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -3,6 +3,7 @@
|
|||||||
|
|
||||||
import * as Utils from 'utils/utils.jsx';
|
import * as Utils from 'utils/utils.jsx';
|
||||||
import Client from 'client/web_client.jsx';
|
import Client from 'client/web_client.jsx';
|
||||||
|
import TeamStore from 'stores/team_store.jsx';
|
||||||
import UserStore from 'stores/user_store.jsx';
|
import UserStore from 'stores/user_store.jsx';
|
||||||
|
|
||||||
import NewChannelModal from './new_channel_modal.jsx';
|
import NewChannelModal from './new_channel_modal.jsx';
|
||||||
@@ -117,7 +118,7 @@ class NewChannelFlow extends React.Component {
|
|||||||
});
|
});
|
||||||
|
|
||||||
this.props.onModalDismissed();
|
this.props.onModalDismissed();
|
||||||
browserHistory.push(Utils.getTeamURLNoOriginFromAddressBar() + '/channels/' + data2.channel.name);
|
browserHistory.push(TeamStore.getCurrentTeamRelativeUrl() + '/channels/' + data2.channel.name);
|
||||||
}
|
}
|
||||||
);
|
);
|
||||||
},
|
},
|
||||||
|
|||||||
@@ -3,6 +3,7 @@
|
|||||||
|
|
||||||
import $ from 'jquery';
|
import $ from 'jquery';
|
||||||
|
|
||||||
|
import TeamStore from 'stores/team_store.jsx';
|
||||||
import UserStore from 'stores/user_store.jsx';
|
import UserStore from 'stores/user_store.jsx';
|
||||||
import {Popover, Overlay} from 'react-bootstrap';
|
import {Popover, Overlay} from 'react-bootstrap';
|
||||||
import * as Utils from 'utils/utils.jsx';
|
import * as Utils from 'utils/utils.jsx';
|
||||||
@@ -36,7 +37,7 @@ export default class PopoverListMembers extends React.Component {
|
|||||||
Utils.openDirectChannelToUser(
|
Utils.openDirectChannelToUser(
|
||||||
teammate,
|
teammate,
|
||||||
(channel, channelAlreadyExisted) => {
|
(channel, channelAlreadyExisted) => {
|
||||||
browserHistory.push(Utils.getTeamURLNoOriginFromAddressBar() + '/channels/' + channel.name);
|
browserHistory.push(TeamStore.getCurrentTeamRelativeUrl() + '/channels/' + channel.name);
|
||||||
if (channelAlreadyExisted) {
|
if (channelAlreadyExisted) {
|
||||||
this.closePopover();
|
this.closePopover();
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -4,10 +4,10 @@
|
|||||||
import $ from 'jquery';
|
import $ from 'jquery';
|
||||||
import ReactDOM from 'react-dom';
|
import ReactDOM from 'react-dom';
|
||||||
import ChannelStore from 'stores/channel_store.jsx';
|
import ChannelStore from 'stores/channel_store.jsx';
|
||||||
|
import TeamStore from 'stores/team_store.jsx';
|
||||||
import UserStore from 'stores/user_store.jsx';
|
import UserStore from 'stores/user_store.jsx';
|
||||||
import BrowserStore from 'stores/browser_store.jsx';
|
import BrowserStore from 'stores/browser_store.jsx';
|
||||||
|
|
||||||
import * as Utils from 'utils/utils.jsx';
|
|
||||||
import {FormattedMessage} from 'react-intl';
|
import {FormattedMessage} from 'react-intl';
|
||||||
import {browserHistory} from 'react-router/es6';
|
import {browserHistory} from 'react-router/es6';
|
||||||
|
|
||||||
@@ -36,7 +36,7 @@ export default class RemovedFromChannelModal extends React.Component {
|
|||||||
var townSquare = ChannelStore.getByName('town-square');
|
var townSquare = ChannelStore.getByName('town-square');
|
||||||
setTimeout(
|
setTimeout(
|
||||||
() => {
|
() => {
|
||||||
browserHistory.push(Utils.getTeamURLNoOriginFromAddressBar() + '/channels/' + townSquare.name);
|
browserHistory.push(TeamStore.getCurrentTeamRelativeUrl() + '/channels/' + townSquare.name);
|
||||||
},
|
},
|
||||||
1);
|
1);
|
||||||
|
|
||||||
|
|||||||
@@ -4,6 +4,7 @@
|
|||||||
import $ from 'jquery';
|
import $ from 'jquery';
|
||||||
import UserProfile from './user_profile.jsx';
|
import UserProfile from './user_profile.jsx';
|
||||||
|
|
||||||
|
import TeamStore from 'stores/team_store.jsx';
|
||||||
import UserStore from 'stores/user_store.jsx';
|
import UserStore from 'stores/user_store.jsx';
|
||||||
|
|
||||||
import * as GlobalActions from 'actions/global_actions.jsx';
|
import * as GlobalActions from 'actions/global_actions.jsx';
|
||||||
@@ -151,7 +152,7 @@ export default class SearchResultsItem extends React.Component {
|
|||||||
this.hideSidebar();
|
this.hideSidebar();
|
||||||
}
|
}
|
||||||
this.shrinkSidebar();
|
this.shrinkSidebar();
|
||||||
browserHistory.push('/' + window.location.pathname.split('/')[1] + '/pl/' + post.id);
|
browserHistory.push(TeamStore.getCurrentTeamRelativeUrl() + '/pl/' + post.id);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
className='search-item__jump'
|
className='search-item__jump'
|
||||||
|
|||||||
@@ -12,7 +12,6 @@ import Constants from 'utils/constants.jsx';
|
|||||||
const ActionTypes = Constants.ActionTypes;
|
const ActionTypes = Constants.ActionTypes;
|
||||||
import * as AsyncClient from 'utils/async_client.jsx';
|
import * as AsyncClient from 'utils/async_client.jsx';
|
||||||
import Client from 'client/web_client.jsx';
|
import Client from 'client/web_client.jsx';
|
||||||
import * as Utils from 'utils/utils.jsx';
|
|
||||||
import ChannelStore from 'stores/channel_store.jsx';
|
import ChannelStore from 'stores/channel_store.jsx';
|
||||||
|
|
||||||
import emojiRoute from 'routes/route_emoji.jsx';
|
import emojiRoute from 'routes/route_emoji.jsx';
|
||||||
@@ -57,7 +56,7 @@ function doChannelChange(state, replace, callback) {
|
|||||||
function preNeedsTeam(nextState, replace, callback) {
|
function preNeedsTeam(nextState, replace, callback) {
|
||||||
// First check to make sure you're in the current team
|
// First check to make sure you're in the current team
|
||||||
// for the current url.
|
// for the current url.
|
||||||
var teamName = Utils.getTeamNameFromUrl();
|
const teamName = nextState.params.team;
|
||||||
var team = TeamStore.getByName(teamName);
|
var team = TeamStore.getByName(teamName);
|
||||||
const oldTeamId = TeamStore.getCurrentId();
|
const oldTeamId = TeamStore.getCurrentId();
|
||||||
|
|
||||||
|
|||||||
@@ -11,12 +11,6 @@ const ActionTypes = Constants.ActionTypes;
|
|||||||
const CHANGE_EVENT = 'change';
|
const CHANGE_EVENT = 'change';
|
||||||
|
|
||||||
var Utils;
|
var Utils;
|
||||||
function getWindowLocationOrigin() {
|
|
||||||
if (!Utils) {
|
|
||||||
Utils = require('utils/utils.jsx'); //eslint-disable-line global-require
|
|
||||||
}
|
|
||||||
return Utils.getWindowLocationOrigin();
|
|
||||||
}
|
|
||||||
|
|
||||||
class TeamStoreClass extends EventEmitter {
|
class TeamStoreClass extends EventEmitter {
|
||||||
constructor() {
|
constructor() {
|
||||||
@@ -87,23 +81,23 @@ class TeamStoreClass extends EventEmitter {
|
|||||||
|
|
||||||
getCurrentTeamUrl() {
|
getCurrentTeamUrl() {
|
||||||
if (this.getCurrent()) {
|
if (this.getCurrent()) {
|
||||||
return getWindowLocationOrigin() + '/' + this.getCurrent().name;
|
return window.mm_config.SiteURL + '/' + this.getCurrent().name;
|
||||||
}
|
}
|
||||||
return null;
|
return '';
|
||||||
}
|
}
|
||||||
|
|
||||||
getCurrentTeamRelativeUrl() {
|
getCurrentTeamRelativeUrl() {
|
||||||
if (this.getCurrent()) {
|
if (this.getCurrent()) {
|
||||||
return '/' + this.getCurrent().name;
|
return '/' + this.getCurrent().name;
|
||||||
}
|
}
|
||||||
return null;
|
return '';
|
||||||
}
|
}
|
||||||
|
|
||||||
getCurrentInviteLink() {
|
getCurrentInviteLink() {
|
||||||
const current = this.getCurrent();
|
const current = this.getCurrent();
|
||||||
|
|
||||||
if (current) {
|
if (current) {
|
||||||
return getWindowLocationOrigin() + '/signup_user_complete/?id=' + current.invite_id;
|
return window.mm_config.SiteURL + '/signup_user_complete/?id=' + current.invite_id;
|
||||||
}
|
}
|
||||||
|
|
||||||
return '';
|
return '';
|
||||||
@@ -112,10 +106,10 @@ class TeamStoreClass extends EventEmitter {
|
|||||||
getTeamUrl(id) {
|
getTeamUrl(id) {
|
||||||
const team = this.get(id);
|
const team = this.get(id);
|
||||||
if (team) {
|
if (team) {
|
||||||
return getWindowLocationOrigin() + '/' + team.name;
|
return window.mm_config.SiteURL + '/' + team.name;
|
||||||
}
|
}
|
||||||
|
|
||||||
return null;
|
return '';
|
||||||
}
|
}
|
||||||
|
|
||||||
saveTeam(team) {
|
saveTeam(team) {
|
||||||
|
|||||||
@@ -99,20 +99,6 @@ export function isSystemAdmin(roles) {
|
|||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
export function getDomainWithOutSub() {
|
|
||||||
var parts = window.location.host.split('.');
|
|
||||||
|
|
||||||
if (parts.length === 1) {
|
|
||||||
if (parts[0].indexOf('dockerhost') > -1) {
|
|
||||||
return 'dockerhost:8065';
|
|
||||||
}
|
|
||||||
|
|
||||||
return 'localhost:8065';
|
|
||||||
}
|
|
||||||
|
|
||||||
return parts[1] + '.' + parts[2];
|
|
||||||
}
|
|
||||||
|
|
||||||
export function getCookie(name) {
|
export function getCookie(name) {
|
||||||
var value = '; ' + document.cookie;
|
var value = '; ' + document.cookie;
|
||||||
var parts = value.split('; ' + name + '=');
|
var parts = value.split('; ' + name + '=');
|
||||||
@@ -171,18 +157,6 @@ export function ding() {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
export function getUrlParameter(sParam) {
|
|
||||||
var sPageURL = window.location.search.substring(1);
|
|
||||||
var sURLVariables = sPageURL.split('&');
|
|
||||||
for (var i = 0; i < sURLVariables.length; i++) {
|
|
||||||
var sParameterName = sURLVariables[i].split('=');
|
|
||||||
if (sParameterName[0] === sParam) {
|
|
||||||
return sParameterName[1];
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return null;
|
|
||||||
}
|
|
||||||
|
|
||||||
export function getDateForUnixTicks(ticks) {
|
export function getDateForUnixTicks(ticks) {
|
||||||
return new Date(ticks);
|
return new Date(ticks);
|
||||||
}
|
}
|
||||||
@@ -1015,18 +989,6 @@ export function displayUsernameForUser(user) {
|
|||||||
return username;
|
return username;
|
||||||
}
|
}
|
||||||
|
|
||||||
//IE10 does not set window.location.origin automatically so this must be called instead when using it
|
|
||||||
export function getWindowLocationOrigin() {
|
|
||||||
var windowLocationOrigin = window.location.origin;
|
|
||||||
if (!windowLocationOrigin) {
|
|
||||||
windowLocationOrigin = window.location.protocol + '//' + window.location.hostname;
|
|
||||||
if (window.location.port) {
|
|
||||||
windowLocationOrigin += ':' + window.location.port;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return windowLocationOrigin;
|
|
||||||
}
|
|
||||||
|
|
||||||
// Converts a file size in bytes into a human-readable string of the form '123MB'.
|
// Converts a file size in bytes into a human-readable string of the form '123MB'.
|
||||||
export function fileSizeToString(bytes) {
|
export function fileSizeToString(bytes) {
|
||||||
// it's unlikely that we'll have files bigger than this
|
// it's unlikely that we'll have files bigger than this
|
||||||
@@ -1045,7 +1007,7 @@ export function fileSizeToString(bytes) {
|
|||||||
|
|
||||||
// Converts a filename (like those attached to Post objects) to a url that can be used to retrieve attachments from the server.
|
// Converts a filename (like those attached to Post objects) to a url that can be used to retrieve attachments from the server.
|
||||||
export function getFileUrl(filename) {
|
export function getFileUrl(filename) {
|
||||||
return getWindowLocationOrigin() + Client.getFilesRoute() + '/get' + filename;
|
return Client.getFilesRoute() + '/get' + filename;
|
||||||
}
|
}
|
||||||
|
|
||||||
// Gets the name of a file (including extension) from a given url or file path.
|
// Gets the name of a file (including extension) from a given url or file path.
|
||||||
@@ -1151,20 +1113,7 @@ export function importSlack(file, success, error) {
|
|||||||
Client.importSlack(formData, success, error);
|
Client.importSlack(formData, success, error);
|
||||||
}
|
}
|
||||||
|
|
||||||
export function getTeamURLFromAddressBar() {
|
export function getShortenedTeamURL(teamURL = '') {
|
||||||
return window.location.origin + '/' + window.location.pathname.split('/')[1];
|
|
||||||
}
|
|
||||||
|
|
||||||
export function getTeamNameFromUrl() {
|
|
||||||
return window.location.pathname.split('/')[1];
|
|
||||||
}
|
|
||||||
|
|
||||||
export function getTeamURLNoOriginFromAddressBar() {
|
|
||||||
return '/' + window.location.pathname.split('/')[1];
|
|
||||||
}
|
|
||||||
|
|
||||||
export function getShortenedTeamURL() {
|
|
||||||
const teamURL = getTeamURLFromAddressBar();
|
|
||||||
if (teamURL.length > 35) {
|
if (teamURL.length > 35) {
|
||||||
return teamURL.substring(0, 10) + '...' + teamURL.substring(teamURL.length - 12, teamURL.length) + '/';
|
return teamURL.substring(0, 10) + '...' + teamURL.substring(teamURL.length - 12, teamURL.length) + '/';
|
||||||
}
|
}
|
||||||
|
|||||||
Ссылка в новой задаче
Block a user