Merge release branch 'release-1.1.0'

Этот коммит содержится в:
Christopher Speller
2015-10-14 08:27:34 -04:00
родитель cbefd88951 4ad9e0673c
Коммит cdbe6342bb
6 изменённых файлов: 70 добавлений и 24 удалений

Просмотреть файл

@@ -15,6 +15,17 @@
<tr>
<td>
<table border="0" cellpadding="0" cellspacing="0" style="padding: 20px 50px 0; text-align: center; margin: 0 auto">
{{if .Props.VerifyUrl }}
<tr>
<td style="border-bottom: 1px solid #ddd; padding: 0 0 20px;">
<h2 style="font-weight: normal; margin-top: 10px;">You've been invited</h2>
<p>Please verify your email address by clicking below.</p>
<p style="margin: 20px 0 15px">
<a href="{{.Props.VerifyUrl}}" style="background: #2389D7; border-radius: 3px; color: #fff; border: none; outline: none; min-width: 200px; padding: 15px 25px; font-size: 14px; font-family: inherit; cursor: pointer; -webkit-appearance: none;text-decoration: none;">Verify Email</a>
</p>
</td>
</tr>
{{end}}
<tr>
<td style="border-bottom: 1px solid #ddd; padding: 0 0 20px;">
<h2 style="font-weight: normal; margin-top: 10px;">You can sign-in to your new team from the web address:</h2>

Просмотреть файл

@@ -198,13 +198,12 @@ func CreateUser(c *Context, team *model.Team, user *model.User) *model.User {
l4g.Error("Encountered an issue joining default channels user_id=%s, team_id=%s, err=%v", ruser.Id, ruser.TeamId, err)
}
fireAndForgetWelcomeEmail(ruser.Email, team.DisplayName, c.GetSiteURL(), c.GetTeamURLFromTeam(team))
fireAndForgetWelcomeEmail(result.Data.(*model.User).Id, ruser.Email, team.Name, team.DisplayName, c.GetSiteURL(), c.GetTeamURLFromTeam(team), user.EmailVerified)
if user.EmailVerified {
if cresult := <-Srv.Store.User().VerifyEmail(ruser.Id); cresult.Err != nil {
l4g.Error("Failed to set email verified err=%v", cresult.Err)
}
} else {
FireAndForgetVerifyEmail(result.Data.(*model.User).Id, ruser.Email, team.Name, team.DisplayName, c.GetSiteURL(), c.GetTeamURLFromTeam(team))
}
ruser.Sanitize(map[string]bool{})
@@ -218,7 +217,7 @@ func CreateUser(c *Context, team *model.Team, user *model.User) *model.User {
}
}
func fireAndForgetWelcomeEmail(email, teamDisplayName, siteURL, teamURL string) {
func fireAndForgetWelcomeEmail(userId, email, teamName, teamDisplayName, siteURL, teamURL string, verified bool) {
go func() {
subjectPage := NewServerTemplatePage("welcome_subject")
@@ -227,10 +226,14 @@ func fireAndForgetWelcomeEmail(email, teamDisplayName, siteURL, teamURL string)
bodyPage.Props["SiteURL"] = siteURL
bodyPage.Props["TeamURL"] = teamURL
if !verified {
link := fmt.Sprintf("%s/verify_email?uid=%s&hid=%s&teamname=%s&email=%s", siteURL, userId, model.HashPassword(userId), teamName, email)
bodyPage.Props["VerifyUrl"] = link
}
if err := utils.SendMail(email, subjectPage.Render(), bodyPage.Render()); err != nil {
l4g.Error("Failed to send welcome email successfully err=%v", err)
}
}()
}

Просмотреть файл

@@ -34,7 +34,7 @@ VOLUME /var/lib/mysql
WORKDIR /mattermost
# Copy over files
ADD https://github.com/mattermost/platform/releases/download/v1.1.0-rc2/mattermost.tar.gz /
ADD https://github.com/mattermost/platform/releases/download/v1.1.0/mattermost.tar.gz /
RUN tar -zxvf /mattermost.tar.gz --strip-components=1 && rm /mattermost.tar.gz
ADD config_docker.json /
ADD docker-entry.sh /

Просмотреть файл

@@ -117,20 +117,51 @@ export default class RhsRootPost extends React.Component {
);
}
let userProfile = <UserProfile userId={post.user_id} />;
let botIndicator;
if (post.props && post.props.from_webhook) {
if (post.props.override_username && global.window.config.EnablePostUsernameOverride === 'true') {
userProfile = (
<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>;
}
let src = '/api/v1/users/' + post.user_id + '/image?time=' + timestamp;
if (post.props && post.props.from_webhook && global.window.config.EnablePostIconOverride === 'true') {
if (post.props.override_icon_url) {
src = post.props.override_icon_url;
}
}
const profilePic = (
<div className='post-profile-img__container'>
<img
className='post-profile-img'
src={src}
height='36'
width='36'
/>
</div>
);
return (
<div className={'post post--root ' + currentUserCss}>
<div className='post-right-channel__name'>{channelName}</div>
<div className='post-profile-img__container'>
<img
className='post-profile-img'
src={'/api/v1/users/' + post.user_id + '/image?time=' + timestamp}
height='36'
width='36'
/>
{profilePic}
</div>
<div className='post__content'>
<ul className='post-header'>
<li className='post-header-col'><strong><UserProfile userId={post.user_id} /></strong></li>
<li className='post-header-col'><strong>{userProfile}</strong></li>
{botIndicator}
<li className='post-header-col'>
<time className='post-profile-time'>
{utils.displayCommentDateTime(post.create_at)}

Просмотреть файл

@@ -148,7 +148,8 @@ export default class ManageIncomingHooks extends React.Component {
return (
<div key='addIncomingHook'>
{'For developers building integrations this page lets you create webhook URLs for channels and private groups. Please see http://mattermost.org/webhooks to learn about creating webhooks, view samples, and to let the community know about integrations you have built. The URLs created below can be used by outside applications to create posts in any channels or private groups you have access to. The specified channel will be used as the default.'}
{'Create webhook URLs for use in external integrations. Please see '}<a href='http://mattermost.org/webhooks'>{'http://mattermost.org/webhooks'}</a> {' to learn more.'}
<br/>
<br/>
<label className='control-label'>{'Add a new incoming webhook'}</label>
<div className='padding-top'>

Просмотреть файл

@@ -59,7 +59,7 @@ export default class UserSettingsGeneralTab extends React.Component {
user.username = username;
this.submitUser(user);
this.submitUser(user, false);
}
submitNickname(e) {
e.preventDefault();
@@ -74,7 +74,7 @@ export default class UserSettingsGeneralTab extends React.Component {
user.nickname = nickname;
this.submitUser(user);
this.submitUser(user, false);
}
submitName(e) {
e.preventDefault();
@@ -91,7 +91,7 @@ export default class UserSettingsGeneralTab extends React.Component {
user.first_name = firstName;
user.last_name = lastName;
this.submitUser(user);
this.submitUser(user, false);
}
submitEmail(e) {
e.preventDefault();
@@ -115,22 +115,22 @@ export default class UserSettingsGeneralTab extends React.Component {
}
user.email = email;
this.submitUser(user);
this.submitUser(user, true);
}
submitUser(user) {
submitUser(user, emailUpdated) {
client.updateUser(user,
function updateSuccess() {
() => {
this.updateSection('');
AsyncClient.getMe();
const verificationEnabled = global.window.config.SendEmailNotifications === 'true' && global.window.config.RequireEmailVerification === 'true';
const verificationEnabled = global.window.config.SendEmailNotifications === 'true' && global.window.config.RequireEmailVerification === 'true' && emailUpdated;
if (verificationEnabled) {
ErrorStore.storeLastError({message: 'Check your email at ' + user.email + ' to verify the address.'});
ErrorStore.emitChange();
this.setState({emailChangeInProgress: true});
}
}.bind(this),
function updateFailure(err) {
},
(err) => {
var state = this.setupInitialState(this.props);
if (err.message) {
state.serverError = err.message;
@@ -138,7 +138,7 @@ export default class UserSettingsGeneralTab extends React.Component {
state.serverError = err;
}
this.setState(state);
}.bind(this)
}
);
}
submitPicture(e) {