Add config options for overriding username and icon, and add BOT indicator next to webhook posts.
Этот коммит содержится в:
@@ -6,6 +6,8 @@
|
|||||||
"GoogleDeveloperKey": "",
|
"GoogleDeveloperKey": "",
|
||||||
"EnableOAuthServiceProvider": false,
|
"EnableOAuthServiceProvider": false,
|
||||||
"EnableIncomingWebhooks": true,
|
"EnableIncomingWebhooks": true,
|
||||||
|
"EnablePostUsernameOverride": false,
|
||||||
|
"EnablePostIconOverride": false,
|
||||||
"EnableTesting": false
|
"EnableTesting": false
|
||||||
},
|
},
|
||||||
"TeamSettings": {
|
"TeamSettings": {
|
||||||
@@ -86,4 +88,4 @@
|
|||||||
"TokenEndpoint": "",
|
"TokenEndpoint": "",
|
||||||
"UserApiEndpoint": ""
|
"UserApiEndpoint": ""
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -6,6 +6,8 @@
|
|||||||
"GoogleDeveloperKey": "",
|
"GoogleDeveloperKey": "",
|
||||||
"EnableOAuthServiceProvider": false,
|
"EnableOAuthServiceProvider": false,
|
||||||
"EnableIncomingWebhooks": true,
|
"EnableIncomingWebhooks": true,
|
||||||
|
"EnablePostUsernameOverride": false,
|
||||||
|
"EnablePostIconOverride": false,
|
||||||
"EnableTesting": false
|
"EnableTesting": false
|
||||||
},
|
},
|
||||||
"TeamSettings": {
|
"TeamSettings": {
|
||||||
|
|||||||
@@ -6,6 +6,8 @@
|
|||||||
"GoogleDeveloperKey": "",
|
"GoogleDeveloperKey": "",
|
||||||
"EnableOAuthServiceProvider": false,
|
"EnableOAuthServiceProvider": false,
|
||||||
"EnableIncomingWebhooks": true,
|
"EnableIncomingWebhooks": true,
|
||||||
|
"EnablePostUsernameOverride": false,
|
||||||
|
"EnablePostIconOverride": false,
|
||||||
"EnableTesting": false
|
"EnableTesting": false
|
||||||
},
|
},
|
||||||
"TeamSettings": {
|
"TeamSettings": {
|
||||||
|
|||||||
@@ -29,6 +29,8 @@ type ServiceSettings struct {
|
|||||||
GoogleDeveloperKey string
|
GoogleDeveloperKey string
|
||||||
EnableOAuthServiceProvider bool
|
EnableOAuthServiceProvider bool
|
||||||
EnableIncomingWebhooks bool
|
EnableIncomingWebhooks bool
|
||||||
|
EnablePostUsernameOverride bool
|
||||||
|
EnablePostIconOverride bool
|
||||||
EnableTesting bool
|
EnableTesting bool
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -184,6 +184,8 @@ func getClientProperties(c *model.Config) map[string]string {
|
|||||||
props["SegmentDeveloperKey"] = c.ServiceSettings.SegmentDeveloperKey
|
props["SegmentDeveloperKey"] = c.ServiceSettings.SegmentDeveloperKey
|
||||||
props["GoogleDeveloperKey"] = c.ServiceSettings.GoogleDeveloperKey
|
props["GoogleDeveloperKey"] = c.ServiceSettings.GoogleDeveloperKey
|
||||||
props["EnableIncomingWebhooks"] = strconv.FormatBool(c.ServiceSettings.EnableIncomingWebhooks)
|
props["EnableIncomingWebhooks"] = strconv.FormatBool(c.ServiceSettings.EnableIncomingWebhooks)
|
||||||
|
props["EnablePostUsernameOverride"] = strconv.FormatBool(c.ServiceSettings.EnablePostUsernameOverride)
|
||||||
|
props["EnablePostIconOverride"] = strconv.FormatBool(c.ServiceSettings.EnablePostIconOverride)
|
||||||
|
|
||||||
props["SendEmailNotifications"] = strconv.FormatBool(c.EmailSettings.SendEmailNotifications)
|
props["SendEmailNotifications"] = strconv.FormatBool(c.EmailSettings.SendEmailNotifications)
|
||||||
props["EnableSignUpWithEmail"] = strconv.FormatBool(c.EmailSettings.EnableSignUpWithEmail)
|
props["EnableSignUpWithEmail"] = strconv.FormatBool(c.EmailSettings.EnableSignUpWithEmail)
|
||||||
|
|||||||
@@ -37,6 +37,8 @@ export default class ServiceSettings extends React.Component {
|
|||||||
config.ServiceSettings.GoogleDeveloperKey = React.findDOMNode(this.refs.GoogleDeveloperKey).value.trim();
|
config.ServiceSettings.GoogleDeveloperKey = React.findDOMNode(this.refs.GoogleDeveloperKey).value.trim();
|
||||||
//config.ServiceSettings.EnableOAuthServiceProvider = React.findDOMNode(this.refs.EnableOAuthServiceProvider).checked;
|
//config.ServiceSettings.EnableOAuthServiceProvider = React.findDOMNode(this.refs.EnableOAuthServiceProvider).checked;
|
||||||
config.ServiceSettings.EnableIncomingWebhooks = React.findDOMNode(this.refs.EnableIncomingWebhooks).checked;
|
config.ServiceSettings.EnableIncomingWebhooks = React.findDOMNode(this.refs.EnableIncomingWebhooks).checked;
|
||||||
|
config.ServiceSettings.EnablePostUsernameOverride = React.findDOMNode(this.refs.EnablePostUsernameOverride).checked;
|
||||||
|
config.ServiceSettings.EnablePostIconOverride = React.findDOMNode(this.refs.EnablePostIconOverride).checked;
|
||||||
config.ServiceSettings.EnableTesting = React.findDOMNode(this.refs.EnableTesting).checked;
|
config.ServiceSettings.EnableTesting = React.findDOMNode(this.refs.EnableTesting).checked;
|
||||||
|
|
||||||
var MaximumLoginAttempts = 10;
|
var MaximumLoginAttempts = 10;
|
||||||
@@ -203,6 +205,72 @@ export default class ServiceSettings extends React.Component {
|
|||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
|
<div className='form-group'>
|
||||||
|
<label
|
||||||
|
className='control-label col-sm-4'
|
||||||
|
htmlFor='EnablePostUsernameOverride'
|
||||||
|
>
|
||||||
|
{'Enable Overriding Usernames from Webhooks: '}
|
||||||
|
</label>
|
||||||
|
<div className='col-sm-8'>
|
||||||
|
<label className='radio-inline'>
|
||||||
|
<input
|
||||||
|
type='radio'
|
||||||
|
name='EnablePostUsernameOverride'
|
||||||
|
value='true'
|
||||||
|
ref='EnablePostUsernameOverride'
|
||||||
|
defaultChecked={this.props.config.ServiceSettings.EnablePostUsernameOverride}
|
||||||
|
onChange={this.handleChange}
|
||||||
|
/>
|
||||||
|
{'true'}
|
||||||
|
</label>
|
||||||
|
<label className='radio-inline'>
|
||||||
|
<input
|
||||||
|
type='radio'
|
||||||
|
name='EnablePostUsernameOverride'
|
||||||
|
value='false'
|
||||||
|
defaultChecked={!this.props.config.ServiceSettings.EnablePostUsernameOverride}
|
||||||
|
onChange={this.handleChange}
|
||||||
|
/>
|
||||||
|
{'false'}
|
||||||
|
</label>
|
||||||
|
<p className='help-text'>{'When true, webhooks will be allowed to change the username they are posting as. Note, combined with allowing icon overriding, this could open users up to phishing attacks.'}</p>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div className='form-group'>
|
||||||
|
<label
|
||||||
|
className='control-label col-sm-4'
|
||||||
|
htmlFor='EnablePostIconOverride'
|
||||||
|
>
|
||||||
|
{'Enable Overriding Icon from Webhooks: '}
|
||||||
|
</label>
|
||||||
|
<div className='col-sm-8'>
|
||||||
|
<label className='radio-inline'>
|
||||||
|
<input
|
||||||
|
type='radio'
|
||||||
|
name='EnablePostIconOverride'
|
||||||
|
value='true'
|
||||||
|
ref='EnablePostIconOverride'
|
||||||
|
defaultChecked={this.props.config.ServiceSettings.EnablePostIconOverride}
|
||||||
|
onChange={this.handleChange}
|
||||||
|
/>
|
||||||
|
{'true'}
|
||||||
|
</label>
|
||||||
|
<label className='radio-inline'>
|
||||||
|
<input
|
||||||
|
type='radio'
|
||||||
|
name='EnablePostIconOverride'
|
||||||
|
value='false'
|
||||||
|
defaultChecked={!this.props.config.ServiceSettings.EnablePostIconOverride}
|
||||||
|
onChange={this.handleChange}
|
||||||
|
/>
|
||||||
|
{'false'}
|
||||||
|
</label>
|
||||||
|
<p className='help-text'>{'When true, webhooks will be allowed to change the icon they post with. Note, combined with allowing username overriding, this could open users up to phishing attacks.'}</p>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
|
||||||
<div className='form-group'>
|
<div className='form-group'>
|
||||||
<label
|
<label
|
||||||
className='control-label col-sm-4'
|
className='control-label col-sm-4'
|
||||||
|
|||||||
@@ -159,8 +159,10 @@ export default class Post extends React.Component {
|
|||||||
var profilePic = null;
|
var profilePic = null;
|
||||||
if (!this.props.hideProfilePic) {
|
if (!this.props.hideProfilePic) {
|
||||||
let src = '/api/v1/users/' + post.user_id + '/image?time=' + timestamp;
|
let src = '/api/v1/users/' + post.user_id + '/image?time=' + timestamp;
|
||||||
if (post.props && post.props.override_icon_url) {
|
if (post.props && post.props.from_webhook && global.window.config.EnablePostIconOverride === 'true') {
|
||||||
src = post.props.override_icon_url;
|
if (post.props.override_icon_url) {
|
||||||
|
src = post.props.override_icon_url;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
profilePic = (
|
profilePic = (
|
||||||
|
|||||||
@@ -13,19 +13,26 @@ export default class PostHeader extends React.Component {
|
|||||||
var post = this.props.post;
|
var post = this.props.post;
|
||||||
|
|
||||||
let userProfile = <UserProfile userId={post.user_id} />;
|
let userProfile = <UserProfile userId={post.user_id} />;
|
||||||
if (post.props && post.props.override_username) {
|
let botIndicator;
|
||||||
userProfile = (
|
|
||||||
<UserProfile
|
if (post.props && post.props.from_webhook) {
|
||||||
userId={post.user_id}
|
if (post.props.override_username && global.window.config.EnablePostUsernameOverride === 'true') {
|
||||||
overwriteName={post.props.override_username}
|
userProfile = (
|
||||||
disablePopover={true}
|
<UserProfile
|
||||||
/>
|
userId={post.user_id}
|
||||||
);
|
overwriteName={post.props.override_username}
|
||||||
|
disablePopover={true}
|
||||||
|
/>
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
botIndicator = <li className='post-header-col post-header__name bot-indicator'>{'BOT'}</li>;
|
||||||
}
|
}
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<ul className='post-header post-header-post'>
|
<ul className='post-header post-header-post'>
|
||||||
<li className='post-header-col post-header__name'><strong>{userProfile}</strong></li>
|
<li className='post-header-col post-header__name'><strong>{userProfile}</strong></li>
|
||||||
|
{botIndicator}
|
||||||
<li className='post-info--hidden'>
|
<li className='post-info--hidden'>
|
||||||
<PostInfo
|
<PostInfo
|
||||||
post={post}
|
post={post}
|
||||||
|
|||||||
@@ -520,13 +520,13 @@ export default class PostList extends React.Component {
|
|||||||
// the previous post was made by the same user as the current post,
|
// the previous post was made by the same user as the current post,
|
||||||
// the previous post is not a comment,
|
// the previous post is not a comment,
|
||||||
// the current post is not a comment,
|
// the current post is not a comment,
|
||||||
// the current profile pic is not overridden
|
// the current post is not from a webhook
|
||||||
// and the previous profile pic is not overridden
|
// and the previous post is not from a webhook
|
||||||
if ((prevPost.user_id === post.user_id) &&
|
if ((prevPost.user_id === post.user_id) &&
|
||||||
!utils.isComment(prevPost) &&
|
!utils.isComment(prevPost) &&
|
||||||
!utils.isComment(post) &&
|
!utils.isComment(post) &&
|
||||||
(!post.props || !post.props.override_icon_url) &&
|
(!post.props || !post.props.from_webhook) &&
|
||||||
(!prevPost.props || !prevPost.props.override_icon_url)) {
|
(!prevPost.props || !prevPost.props.from_webhook)) {
|
||||||
hideProfilePic = true;
|
hideProfilePic = true;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -509,3 +509,11 @@ body.ios {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
.bot-indicator {
|
||||||
|
background-color: lightgrey;
|
||||||
|
border-radius:2px;
|
||||||
|
padding-left:2px;
|
||||||
|
padding-right:2px;
|
||||||
|
font-family:"Courier New"
|
||||||
|
}
|
||||||
|
|||||||
11
web/web.go
11
web/web.go
@@ -843,6 +843,12 @@ func getAccessToken(c *api.Context, w http.ResponseWriter, r *http.Request) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
func incomingWebhook(c *api.Context, w http.ResponseWriter, r *http.Request) {
|
func incomingWebhook(c *api.Context, w http.ResponseWriter, r *http.Request) {
|
||||||
|
if !utils.Cfg.ServiceSettings.EnableIncomingWebhooks {
|
||||||
|
c.Err = model.NewAppError("incomingWebhook", "Incoming webhooks have been disabled by the system admin.", "")
|
||||||
|
c.Err.StatusCode = http.StatusNotImplemented
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
params := mux.Vars(r)
|
params := mux.Vars(r)
|
||||||
id := params["id"]
|
id := params["id"]
|
||||||
|
|
||||||
@@ -913,12 +919,13 @@ func incomingWebhook(c *api.Context, w http.ResponseWriter, r *http.Request) {
|
|||||||
pchan := api.Srv.Store.Channel().CheckPermissionsTo(hook.TeamId, channel.Id, hook.UserId)
|
pchan := api.Srv.Store.Channel().CheckPermissionsTo(hook.TeamId, channel.Id, hook.UserId)
|
||||||
|
|
||||||
post := &model.Post{UserId: hook.UserId, ChannelId: channel.Id, Message: text}
|
post := &model.Post{UserId: hook.UserId, ChannelId: channel.Id, Message: text}
|
||||||
|
post.AddProp("from_webhook", "true")
|
||||||
|
|
||||||
if len(overrideUsername) != 0 {
|
if len(overrideUsername) != 0 && utils.Cfg.ServiceSettings.EnablePostUsernameOverride {
|
||||||
post.AddProp("override_username", overrideUsername)
|
post.AddProp("override_username", overrideUsername)
|
||||||
}
|
}
|
||||||
|
|
||||||
if len(overrideIconUrl) != 0 {
|
if len(overrideIconUrl) != 0 && utils.Cfg.ServiceSettings.EnablePostIconOverride {
|
||||||
post.AddProp("override_icon_url", overrideIconUrl)
|
post.AddProp("override_icon_url", overrideIconUrl)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
Ссылка в новой задаче
Block a user