mirror of
https://github.com/mattermost/mattermost.git
synced 2025-02-25 18:55:24 -06:00
commit
0cd93cf2da
@ -19,12 +19,16 @@ var commands = []commandHandler{
|
||||
logoutCommand,
|
||||
joinCommand,
|
||||
loadTestCommand,
|
||||
echoCommand,
|
||||
}
|
||||
|
||||
func InitCommand(r *mux.Router) {
|
||||
l4g.Debug("Initializing command api routes")
|
||||
r.Handle("/command", ApiUserRequired(command)).Methods("POST")
|
||||
|
||||
if utils.Cfg.TeamSettings.AllowValet {
|
||||
commands = append(commands, echoCommand)
|
||||
}
|
||||
|
||||
hub.Start()
|
||||
}
|
||||
|
||||
|
@ -114,7 +114,7 @@ func uploadFile(c *Context, w http.ResponseWriter, r *http.Request) {
|
||||
return
|
||||
}
|
||||
|
||||
fileUrl := c.TeamUrl + "/api/v1/files/get/" + channelId + "/" + c.Session.UserId + "/" + uid + "/" + files[i].Filename
|
||||
fileUrl := c.TeamUrl + "/api/v1/files/get/" + channelId + "/" + c.Session.UserId + "/" + uid + "/" + url.QueryEscape(files[i].Filename)
|
||||
resStruct.Filenames = append(resStruct.Filenames, fileUrl)
|
||||
}
|
||||
|
||||
|
@ -58,6 +58,12 @@ func createPost(c *Context, w http.ResponseWriter, r *http.Request) {
|
||||
}
|
||||
|
||||
func createValetPost(c *Context, w http.ResponseWriter, r *http.Request) {
|
||||
if !utils.Cfg.TeamSettings.AllowValet {
|
||||
c.Err = model.NewAppError("createValetPost", "The valet feature is currently turned off. Please contact your system administrator for details.", "")
|
||||
c.Err.StatusCode = http.StatusNotImplemented
|
||||
return
|
||||
}
|
||||
|
||||
post := model.PostFromJson(r.Body)
|
||||
if post == nil {
|
||||
c.SetInvalidParam("createValetPost", "post")
|
||||
|
@ -147,62 +147,70 @@ func TestCreateValetPost(t *testing.T) {
|
||||
channel2 := &model.Channel{DisplayName: "Test API Name", Name: "a" + model.NewId() + "a", Type: model.CHANNEL_OPEN, TeamId: team.Id}
|
||||
channel2 = Client.Must(Client.CreateChannel(channel2)).Data.(*model.Channel)
|
||||
|
||||
post1 := &model.Post{ChannelId: channel1.Id, Message: "#hashtag a" + model.NewId() + "a"}
|
||||
rpost1, err := Client.CreateValetPost(post1)
|
||||
if err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
if utils.Cfg.TeamSettings.AllowValet {
|
||||
post1 := &model.Post{ChannelId: channel1.Id, Message: "#hashtag a" + model.NewId() + "a"}
|
||||
rpost1, err := Client.CreateValetPost(post1)
|
||||
if err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
|
||||
if rpost1.Data.(*model.Post).Message != post1.Message {
|
||||
t.Fatal("message didn't match")
|
||||
}
|
||||
if rpost1.Data.(*model.Post).Message != post1.Message {
|
||||
t.Fatal("message didn't match")
|
||||
}
|
||||
|
||||
if rpost1.Data.(*model.Post).Hashtags != "#hashtag" {
|
||||
t.Fatal("hashtag didn't match")
|
||||
}
|
||||
if rpost1.Data.(*model.Post).Hashtags != "#hashtag" {
|
||||
t.Fatal("hashtag didn't match")
|
||||
}
|
||||
|
||||
post2 := &model.Post{ChannelId: channel1.Id, Message: "a" + model.NewId() + "a", RootId: rpost1.Data.(*model.Post).Id}
|
||||
rpost2, err := Client.CreateValetPost(post2)
|
||||
if err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
post2 := &model.Post{ChannelId: channel1.Id, Message: "a" + model.NewId() + "a", RootId: rpost1.Data.(*model.Post).Id}
|
||||
rpost2, err := Client.CreateValetPost(post2)
|
||||
if err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
|
||||
post3 := &model.Post{ChannelId: channel1.Id, Message: "a" + model.NewId() + "a", RootId: rpost1.Data.(*model.Post).Id, ParentId: rpost2.Data.(*model.Post).Id}
|
||||
_, err = Client.CreateValetPost(post3)
|
||||
if err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
post3 := &model.Post{ChannelId: channel1.Id, Message: "a" + model.NewId() + "a", RootId: rpost1.Data.(*model.Post).Id, ParentId: rpost2.Data.(*model.Post).Id}
|
||||
_, err = Client.CreateValetPost(post3)
|
||||
if err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
|
||||
post4 := &model.Post{ChannelId: "junk", Message: "a" + model.NewId() + "a"}
|
||||
_, err = Client.CreateValetPost(post4)
|
||||
if err.StatusCode != http.StatusForbidden {
|
||||
t.Fatal("Should have been forbidden")
|
||||
}
|
||||
post4 := &model.Post{ChannelId: "junk", Message: "a" + model.NewId() + "a"}
|
||||
_, err = Client.CreateValetPost(post4)
|
||||
if err.StatusCode != http.StatusForbidden {
|
||||
t.Fatal("Should have been forbidden")
|
||||
}
|
||||
|
||||
Client.LoginByEmail(team.Domain, user2.Email, "pwd")
|
||||
post5 := &model.Post{ChannelId: channel1.Id, Message: "a" + model.NewId() + "a"}
|
||||
_, err = Client.CreateValetPost(post5)
|
||||
if err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
Client.LoginByEmail(team.Domain, user2.Email, "pwd")
|
||||
post5 := &model.Post{ChannelId: channel1.Id, Message: "a" + model.NewId() + "a"}
|
||||
_, err = Client.CreateValetPost(post5)
|
||||
if err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
|
||||
user3 := &model.User{TeamId: team2.Id, Email: model.NewId() + "corey@test.com", FullName: "Corey Hulen", Password: "pwd"}
|
||||
user3 = Client.Must(Client.CreateUser(user3, "")).Data.(*model.User)
|
||||
Srv.Store.User().VerifyEmail(user3.Id)
|
||||
user3 := &model.User{TeamId: team2.Id, Email: model.NewId() + "corey@test.com", FullName: "Corey Hulen", Password: "pwd"}
|
||||
user3 = Client.Must(Client.CreateUser(user3, "")).Data.(*model.User)
|
||||
Srv.Store.User().VerifyEmail(user3.Id)
|
||||
|
||||
Client.LoginByEmail(team2.Domain, user3.Email, "pwd")
|
||||
Client.LoginByEmail(team2.Domain, user3.Email, "pwd")
|
||||
|
||||
channel3 := &model.Channel{DisplayName: "Test API Name", Name: "a" + model.NewId() + "a", Type: model.CHANNEL_OPEN, TeamId: team2.Id}
|
||||
channel3 = Client.Must(Client.CreateChannel(channel3)).Data.(*model.Channel)
|
||||
channel3 := &model.Channel{DisplayName: "Test API Name", Name: "a" + model.NewId() + "a", Type: model.CHANNEL_OPEN, TeamId: team2.Id}
|
||||
channel3 = Client.Must(Client.CreateChannel(channel3)).Data.(*model.Channel)
|
||||
|
||||
post6 := &model.Post{ChannelId: channel1.Id, Message: "a" + model.NewId() + "a"}
|
||||
_, err = Client.CreateValetPost(post6)
|
||||
if err.StatusCode != http.StatusForbidden {
|
||||
t.Fatal("Should have been forbidden")
|
||||
}
|
||||
post6 := &model.Post{ChannelId: channel1.Id, Message: "a" + model.NewId() + "a"}
|
||||
_, err = Client.CreateValetPost(post6)
|
||||
if err.StatusCode != http.StatusForbidden {
|
||||
t.Fatal("Should have been forbidden")
|
||||
}
|
||||
|
||||
if _, err = Client.DoPost("/channels/"+channel3.Id+"/create", "garbage"); err == nil {
|
||||
t.Fatal("should have been an error")
|
||||
if _, err = Client.DoPost("/channels/"+channel3.Id+"/create", "garbage"); err == nil {
|
||||
t.Fatal("should have been an error")
|
||||
}
|
||||
} else {
|
||||
post1 := &model.Post{ChannelId: channel1.Id, Message: "#hashtag a" + model.NewId() + "a"}
|
||||
_, err := Client.CreateValetPost(post1)
|
||||
if err.StatusCode != http.StatusNotImplemented {
|
||||
t.Fatal("Should have failed with 501 - Not Implemented")
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -157,9 +157,11 @@ func createTeamFromSignup(c *Context, w http.ResponseWriter, r *http.Request) {
|
||||
return
|
||||
}
|
||||
|
||||
CreateValet(c, rteam)
|
||||
if c.Err != nil {
|
||||
return
|
||||
if utils.Cfg.TeamSettings.AllowValet {
|
||||
CreateValet(c, rteam)
|
||||
if c.Err != nil {
|
||||
return
|
||||
}
|
||||
}
|
||||
|
||||
InviteMembers(rteam, ruser, teamSignup.Invites)
|
||||
|
@ -145,6 +145,10 @@ func createUser(c *Context, w http.ResponseWriter, r *http.Request) {
|
||||
}
|
||||
|
||||
func CreateValet(c *Context, team *model.Team) *model.User {
|
||||
if !utils.Cfg.TeamSettings.AllowValet {
|
||||
return &model.User{}
|
||||
}
|
||||
|
||||
valet := &model.User{}
|
||||
valet.TeamId = team.Id
|
||||
valet.Email = utils.Cfg.EmailSettings.FeedbackEmail
|
||||
|
@ -72,6 +72,7 @@
|
||||
"TeamSettings": {
|
||||
"MaxUsersPerTeam": 150,
|
||||
"AllowPublicLink": true,
|
||||
"AllowValet": false,
|
||||
"TermsLink": "/static/help/configure_links.html",
|
||||
"PrivacyLink": "/static/help/configure_links.html",
|
||||
"AboutLink": "/static/help/configure_links.html",
|
||||
|
@ -96,6 +96,7 @@ type PrivacySettings struct {
|
||||
type TeamSettings struct {
|
||||
MaxUsersPerTeam int
|
||||
AllowPublicLink bool
|
||||
AllowValet bool
|
||||
TermsLink string
|
||||
PrivacyLink string
|
||||
AboutLink string
|
||||
|
@ -55,12 +55,15 @@ module.exports = React.createClass({
|
||||
|
||||
}.bind(this),
|
||||
function(err) {
|
||||
var state = {}
|
||||
var state = {};
|
||||
state.server_error = err.message;
|
||||
this.setState(state);
|
||||
|
||||
if (err.message === "Invalid RootId parameter") {
|
||||
if ($('#post_deleted').length > 0) $('#post_deleted').modal('show');
|
||||
}
|
||||
else {
|
||||
this.setState(state);
|
||||
}
|
||||
}.bind(this)
|
||||
);
|
||||
},
|
||||
|
@ -56,7 +56,7 @@ module.exports = React.createClass({
|
||||
<div>
|
||||
<h4>Find Your Team</h4>
|
||||
<form onSubmit={this.handleSubmit}>
|
||||
<p>{"An email will be sent to this address with links to any " + strings.TeamPlural}</p>
|
||||
<p>{"We'll send you an email with links to your " + strings.TeamPlural + "."}</p>
|
||||
<div className="form-group">
|
||||
<label className='control-label'>Email</label>
|
||||
<div className={ email_error ? "form-group has-error" : "form-group" }>
|
||||
|
@ -23,7 +23,7 @@ module.exports = React.createClass({
|
||||
<p>Someone deleted the message on which you tried to post a comment.</p>
|
||||
</div>
|
||||
<div className="modal-footer">
|
||||
<button type="button" className="btn btn-primary" data-dismiss="modal">Agree</button>
|
||||
<button type="button" className="btn btn-primary" data-dismiss="modal">Okay</button>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
@ -14,11 +14,13 @@ module.exports = React.createClass({
|
||||
<li className={this.props.activeTab == 'general' ? 'active' : ''}><a href="#" onClick={function(){self.updateTab("general");}}><i className="glyphicon glyphicon-cog"></i>General</a></li>
|
||||
<li className={this.props.activeTab == 'security' ? 'active' : ''}><a href="#" onClick={function(){self.updateTab("security");}}><i className="glyphicon glyphicon-lock"></i>Security</a></li>
|
||||
<li className={this.props.activeTab == 'notifications' ? 'active' : ''}><a href="#" onClick={function(){self.updateTab("notifications");}}><i className="glyphicon glyphicon-exclamation-sign"></i>Notifications</a></li>
|
||||
<li className={this.props.activeTab == 'sessions' ? 'active' : ''}><a href="#" onClick={function(){self.updateTab("sessions");}}><i className="glyphicon glyphicon-globe"></i>Sessions</a></li>
|
||||
<li className={this.props.activeTab == 'activity_log' ? 'active' : ''}><a href="#" onClick={function(){self.updateTab("activity_log");}}><i className="glyphicon glyphicon-time"></i>Activity Log</a></li>
|
||||
<li className={this.props.activeTab == 'appearance' ? 'active' : ''}><a href="#" onClick={function(){self.updateTab("appearance");}}><i className="glyphicon glyphicon-wrench"></i>Appearance</a></li>
|
||||
</ul>
|
||||
</div>
|
||||
);
|
||||
/* Temporarily removing sessions and activity logs
|
||||
<li className={this.props.activeTab == 'sessions' ? 'active' : ''}><a href="#" onClick={function(){self.updateTab("sessions");}}><i className="glyphicon glyphicon-globe"></i>Sessions</a></li>
|
||||
<li className={this.props.activeTab == 'activity_log' ? 'active' : ''}><a href="#" onClick={function(){self.updateTab("activity_log");}}><i className="glyphicon glyphicon-time"></i>Activity Log</a></li>
|
||||
*/
|
||||
}
|
||||
});
|
||||
|
@ -1126,6 +1126,9 @@ module.exports = React.createClass({
|
||||
<NotificationsTab user={this.state.user} activeSection={this.props.activeSection} updateSection={this.props.updateSection} />
|
||||
</div>
|
||||
);
|
||||
|
||||
/* Temporarily removing sessions and activity_log tabs
|
||||
|
||||
} else if (this.props.activeTab === 'sessions') {
|
||||
return (
|
||||
<div>
|
||||
@ -1138,6 +1141,8 @@ module.exports = React.createClass({
|
||||
<AuditTab activeSection={this.props.activeSection} updateSection={this.props.updateSection} />
|
||||
</div>
|
||||
);
|
||||
*/
|
||||
|
||||
} else if (this.props.activeTab === 'appearance') {
|
||||
return (
|
||||
<div>
|
||||
|
@ -165,7 +165,7 @@ module.exports = React.createClass({
|
||||
<span className="text"> | </span>
|
||||
</div>
|
||||
: "" }
|
||||
<a href={this.props.filenames[id]} download={name} className="text">Download</a>
|
||||
<a href={this.props.filenames[id]} download={decodeURIComponent(name)} className="text">Download</a>
|
||||
</div>
|
||||
</div>
|
||||
{loading}
|
||||
|
@ -4,12 +4,12 @@
|
||||
|
||||
module.exports.track = function(category, action, label, prop, val) {
|
||||
global.window.snowplow('trackStructEvent', category, action, label, prop, val);
|
||||
if (global.window.analytics != null) global.window.analytics.track(action, {category: category, label: label, property: prop, value: val});
|
||||
global.window.analytics.track(action, {category: category, label: label, property: prop, value: val});
|
||||
};
|
||||
|
||||
module.exports.trackPage = function() {
|
||||
global.window.snowplow('trackPageView');
|
||||
if (global.window.analytics != null) global.window.analytics.page();
|
||||
global.window.analytics.page();
|
||||
};
|
||||
|
||||
function handleError(method_name, xhr, status, err) {
|
||||
|
@ -36,6 +36,7 @@
|
||||
window._LTracker = _LTracker;
|
||||
_LTracker.push({'logglyKey': config.LogglyWriteKey, 'sendConsoleErrors' : config.LogglyConsoleErrors });
|
||||
} else {
|
||||
window._LTracker = [];
|
||||
console.warn("config.js missing LogglyWriteKey, Loggly analytics is not reporting");
|
||||
}
|
||||
</script>
|
||||
@ -58,26 +59,34 @@
|
||||
analytics.page();
|
||||
}}();
|
||||
} else {
|
||||
analytics = {};
|
||||
analytics.page = function(){};
|
||||
analytics.track = function(){};
|
||||
console.warn("config.js missing SegmentWriteKey, SegmentIO analytics is not tracking");
|
||||
}
|
||||
</script>
|
||||
<!-- Snowplow starts plowing -->
|
||||
<script type="text/javascript">
|
||||
;(function(p,l,o,w,i,n,g){if(!p[i]){p.GlobalSnowplowNamespace=p.GlobalSnowplowNamespace||[];
|
||||
p.GlobalSnowplowNamespace.push(i);p[i]=function(){(p[i].q=p[i].q||[]).push(arguments)
|
||||
};p[i].q=p[i].q||[];n=l.createElement(o);g=l.getElementsByTagName(o)[0];n.async=1;
|
||||
n.src=w;g.parentNode.insertBefore(n,g)}}(window,document,"script","//d1fc8wv8zag5ca.cloudfront.net/2.4.2/sp.js","snowplow"));
|
||||
if ('{{ .Props.AnalyticsUrl }}'.trim() !== '') {
|
||||
;(function(p,l,o,w,i,n,g){if(!p[i]){p.GlobalSnowplowNamespace=p.GlobalSnowplowNamespace||[];
|
||||
p.GlobalSnowplowNamespace.push(i);p[i]=function(){(p[i].q=p[i].q||[]).push(arguments)
|
||||
};p[i].q=p[i].q||[];n=l.createElement(o);g=l.getElementsByTagName(o)[0];n.async=1;
|
||||
n.src=w;g.parentNode.insertBefore(n,g)}}(window,document,"script","//d1fc8wv8zag5ca.cloudfront.net/2.4.2/sp.js","snowplow"));
|
||||
|
||||
window.snowplow('newTracker', 'cf', '{{ .Props.AnalyticsUrl }}', {
|
||||
appId: '{{ .SiteName }}'
|
||||
});
|
||||
window.snowplow('newTracker', 'cf', '{{ .Props.AnalyticsUrl }}', {
|
||||
appId: '{{ .SiteName }}'
|
||||
});
|
||||
|
||||
var user = window.UserStore.getCurrentUser(true);
|
||||
if (user) {
|
||||
window.snowplow('setUserId', user.id);
|
||||
var user = window.UserStore.getCurrentUser(true);
|
||||
if (user) {
|
||||
window.snowplow('setUserId', user.id);
|
||||
}
|
||||
|
||||
window.snowplow('trackPageView');
|
||||
} else {
|
||||
window.snowplow = function(){};
|
||||
console.warn("config.json missing AnalyticsUrl, Snowplow analytics is not tracking");
|
||||
}
|
||||
|
||||
window.snowplow('trackPageView');
|
||||
</script>
|
||||
<!-- Snowplow stops plowing -->
|
||||
</head>
|
||||
|
Loading…
Reference in New Issue
Block a user