summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--api/file.go3
-rw-r--r--doc/README.md1
-rw-r--r--doc/api/Overview.md94
-rw-r--r--doc/install/Production-Ubuntu.md2
-rw-r--r--web/react/components/activity_log_modal.jsx5
-rw-r--r--web/react/components/admin_console/admin_controller.jsx2
-rw-r--r--web/react/components/admin_console/admin_sidebar.jsx272
-rw-r--r--web/react/components/admin_console/email_settings.jsx8
-rw-r--r--web/react/components/admin_console/image_settings.jsx2
-rw-r--r--web/react/components/admin_console/log_settings.jsx2
-rw-r--r--web/react/components/email_verify.jsx4
-rw-r--r--web/react/components/get_link_modal.jsx29
-rw-r--r--web/react/components/login.jsx12
-rw-r--r--web/react/components/signup_user_complete.jsx27
-rw-r--r--web/react/components/user_settings/import_theme_modal.jsx1
-rw-r--r--web/react/package.json1
-rw-r--r--web/react/utils/constants.jsx35
-rw-r--r--web/react/utils/utils.jsx24
-rw-r--r--web/sass-files/sass/partials/_access-history.scss2
-rw-r--r--web/sass-files/sass/partials/_activity-log.scss19
-rw-r--r--web/sass-files/sass/partials/_admin-console.scss329
-rw-r--r--web/sass-files/sass/partials/_base.scss11
-rw-r--r--web/sass-files/sass/partials/_headers.scss1
-rw-r--r--web/sass-files/sass/partials/_mentions.scss8
-rw-r--r--web/sass-files/sass/partials/_modal.scss3
-rw-r--r--web/sass-files/sass/partials/_post.scss2
-rw-r--r--web/sass-files/sass/partials/_post_right.scss2
-rw-r--r--web/sass-files/sass/partials/_search.scss10
-rw-r--r--web/sass-files/sass/partials/_settings.scss4
-rw-r--r--web/sass-files/sass/partials/_signup.scss8
-rw-r--r--web/templates/admin_console.html8
-rw-r--r--web/templates/verify.html25
-rw-r--r--web/web.go15
33 files changed, 570 insertions, 401 deletions
diff --git a/api/file.go b/api/file.go
index 5dc1db650..bb9aa00d8 100644
--- a/api/file.go
+++ b/api/file.go
@@ -23,7 +23,6 @@ import (
"image/jpeg"
"io"
"io/ioutil"
- "mime"
"net/http"
"net/url"
"os"
@@ -407,7 +406,7 @@ func getFile(c *Context, w http.ResponseWriter, r *http.Request) {
w.Header().Set("Cache-Control", "max-age=2592000, public")
w.Header().Set("Content-Length", strconv.Itoa(len(f)))
- w.Header().Set("Content-Type", mime.TypeByExtension(filepath.Ext(filename)))
+ w.Header().Del("Content-Type") // Content-Type will be set automatically by the http writer
// attach extra headers to trigger a download on IE and Edge
ua := user_agent.New(r.UserAgent())
diff --git a/doc/README.md b/doc/README.md
index d711b5d53..66af8f34c 100644
--- a/doc/README.md
+++ b/doc/README.md
@@ -19,6 +19,7 @@
- [Code Contribution Guidelines](developer/Code-Contribution-Guidelines.md)
- [Developer Machine Setup](developer/Setup.md)
- [Mattermost Style Guide](developer/Style-Guide.md)
+- [API Overview] (api/Overview.md)
## Usage Help
diff --git a/doc/api/Overview.md b/doc/api/Overview.md
new file mode 100644
index 000000000..02e11974e
--- /dev/null
+++ b/doc/api/Overview.md
@@ -0,0 +1,94 @@
+# API Overview
+
+This provides a basic overview of the Mattermost API. All examples assume there is a Mattermost instance running at http://localhost:8065.
+
+## Schema
+
+All API access is done through `yourdomain.com/api/v1/`, with all data being sent and received as JSON.
+
+
+## Authentication
+
+The majority of the Mattermost API involves interacting with teams. Therefore, most API methods require authentication as a user. There are two ways to authenticate into a Mattermost system.
+
+##### Session Token
+
+Make an HTTP POST to `yourdomain.com/api/v1/users/login` with a JSON body indicating the `name` of the team, the user's `email` and `password`.
+
+```
+curl -i -d '{"name":"exampleteam","email":"someone@nowhere.com","password":"thisisabadpassword"}' http://localhost:8065/api/v1/users/login
+```
+
+If successful, the response will contain a `Token` header and a User object in the body.
+
+```
+HTTP/1.1 200 OK
+Set-Cookie: MMSID=hyr5dmb1mbb49c44qmx4whniso; Path=/; Max-Age=2592000; HttpOnly
+Token: hyr5dmb1mbb49c44qmx4whniso
+X-Ratelimit-Limit: 10
+X-Ratelimit-Remaining: 9
+X-Ratelimit-Reset: 1
+X-Request-Id: smda55ckcfy89b6tia58shk5fh
+X-Version-Id: developer
+Date: Fri, 11 Sep 2015 13:21:14 GMT
+Content-Length: 657
+Content-Type: application/json; charset=utf-8
+
+{{user object as json}}
+```
+
+Include the `Token` as part of the `Authentication` header on your future API requests with the `Bearer` method.
+
+```
+curl -i -H 'Authorization: Bearer hyr5dmb1mbb49c44qmx4whniso' http://localhost:8065/api/v1/users/me
+```
+
+That's it! You should now be able to access the API as the user you logged in as.
+
+##### OAuth2
+
+Coming soon...
+
+
+## Client Errors
+
+All errors will return an appropriate HTTP response code along with the following JSON body:
+
+```
+{
+ "message": "", // the reason for the error
+ "detailed_error": "", // some extra details about the error
+ "request_id": "", // the ID of the request
+ "status_code": 0 // the HTTP status code
+}
+```
+
+
+## Rate Limiting
+
+Whenever you make an HTTP request to the Mattermost API you might notice the following headers included in the response:
+```
+X-Ratelimit-Limit: 10
+X-Ratelimit-Remaining: 9
+X-Ratelimit-Reset: 1441983590
+
+```
+
+These headers are telling you your current rate limit status.
+
+Header | Description
+--------------------- | -----------
+X-Ratelimit-Limit | The maximum number of requests you can make per second.
+X-Ratelimit-Remaining | The number of requests remaining in the current window.
+X-Ratelimit-Reset | The remaining UTC epoch seconds before the rate limit resets.
+
+If you exceed your rate limit for a window you will receive the following error in the body of the response:
+```
+HTTP/1.1 429 Too Many Requests
+Date: Tue, 10 Sep 2015 11:20:28 GMT
+X-RateLimit-Limit: 10
+X-RateLimit-Remaining: 0
+X-RateLimit-Reset: 1
+
+limit exceeded
+```
diff --git a/doc/install/Production-Ubuntu.md b/doc/install/Production-Ubuntu.md
index 0f1373c1a..05a56c412 100644
--- a/doc/install/Production-Ubuntu.md
+++ b/doc/install/Production-Ubuntu.md
@@ -8,7 +8,7 @@
## Set up Database Server
1. For the purposes of this guide we will assume this server has an IP address of 10.10.10.1
-1. Install PostgreSQL 9.3+ (or MySQL 5.2+)
+1. Install PostgreSQL 9.3+ (or MySQL 5.6+)
* ``` sudo apt-get install postgresql postgresql-contrib```
1. PostgreSQL created a user account called `postgres`. You will need to log into that account with:
* ``` sudo -i -u postgres```
diff --git a/web/react/components/activity_log_modal.jsx b/web/react/components/activity_log_modal.jsx
index aee2541b5..ff370c32e 100644
--- a/web/react/components/activity_log_modal.jsx
+++ b/web/react/components/activity_log_modal.jsx
@@ -31,6 +31,11 @@ export default class ActivityLogModal extends React.Component {
}
submitRevoke(altId, e) {
e.preventDefault();
+ var modalContent = $(e.target).closest('.modal-content');
+ modalContent.addClass('animation--highlight');
+ setTimeout(() => {
+ modalContent.removeClass('animation--highlight');
+ }, 1500);
Client.revokeSession(altId,
function handleRevokeSuccess() {
AsyncClient.getSessions();
diff --git a/web/react/components/admin_console/admin_controller.jsx b/web/react/components/admin_console/admin_controller.jsx
index 92f0bbdce..f40e48f70 100644
--- a/web/react/components/admin_console/admin_controller.jsx
+++ b/web/react/components/admin_console/admin_controller.jsx
@@ -147,7 +147,7 @@ export default class AdminController extends React.Component {
}
return (
- <div className='container-fluid'>
+ <div>
<div
className='sidebar--menu'
id='sidebar-menu'
diff --git a/web/react/components/admin_console/admin_sidebar.jsx b/web/react/components/admin_console/admin_sidebar.jsx
index 4b9ff3cb8..f102661b2 100644
--- a/web/react/components/admin_console/admin_sidebar.jsx
+++ b/web/react/components/admin_console/admin_sidebar.jsx
@@ -129,141 +129,143 @@ export default class AdminSidebar extends React.Component {
<div className='sidebar--left sidebar--collapsable'>
<div>
<AdminSidebarHeader />
- <ul className='nav nav-pills nav-stacked'>
- <li>
- <ul className='nav nav__sub-menu'>
- <li>
- <h4>
- <span className='icon fa fa-gear'></span>
- <span>{'SETTINGS'}</span>
- </h4>
- </li>
- </ul>
- <ul className='nav nav__sub-menu padded'>
- <li>
- <a
- href='#'
- className={this.isSelected('service_settings')}
- onClick={this.handleClick.bind(this, 'service_settings', null)}
- >
- {'Service Settings'}
- </a>
- </li>
- <li>
- <a
- href='#'
- className={this.isSelected('team_settings')}
- onClick={this.handleClick.bind(this, 'team_settings', null)}
- >
- {'Team Settings'}
- </a>
- </li>
- <li>
- <a
- href='#'
- className={this.isSelected('sql_settings')}
- onClick={this.handleClick.bind(this, 'sql_settings', null)}
- >
- {'SQL Settings'}
- </a>
- </li>
- <li>
- <a
- href='#'
- className={this.isSelected('email_settings')}
- onClick={this.handleClick.bind(this, 'email_settings', null)}
- >
- {'Email Settings'}
- </a>
- </li>
- <li>
- <a
- href='#'
- className={this.isSelected('image_settings')}
- onClick={this.handleClick.bind(this, 'image_settings', null)}
- >
- {'File Settings'}
- </a>
- </li>
- <li>
- <a
- href='#'
- className={this.isSelected('log_settings')}
- onClick={this.handleClick.bind(this, 'log_settings', null)}
- >
- {'Log Settings'}
- </a>
- </li>
- <li>
- <a
- href='#'
- className={this.isSelected('rate_settings')}
- onClick={this.handleClick.bind(this, 'rate_settings', null)}
- >
- {'Rate Limit Settings'}
- </a>
- </li>
- <li>
- <a
- href='#'
- className={this.isSelected('privacy_settings')}
- onClick={this.handleClick.bind(this, 'privacy_settings', null)}
- >
- {'Privacy Settings'}
- </a>
- </li>
- <li>
- <a
- href='#'
- className={this.isSelected('gitlab_settings')}
- onClick={this.handleClick.bind(this, 'gitlab_settings', null)}
- >
- {'GitLab Settings'}
- </a>
- </li>
- </ul>
- <ul className='nav nav__sub-menu'>
- <li>
- <h4>
- <span className='icon fa fa-gear'></span>
- <span>{'TEAMS (' + count + ')'}</span>
- <span className='menu-icon--right'>
- <a
- href='#'
- onClick={this.showTeamSelect}
- >
- <i className='fa fa-plus'></i>
- </a>
- </span>
- </h4>
- </li>
- </ul>
- <ul className='nav nav__sub-menu padded'>
- <li>
- {teams}
- </li>
- </ul>
- <ul className='nav nav__sub-menu'>
- <li>
- <h4>
- <span className='icon fa fa-gear'></span>
- <span>{'OTHER'}</span>
- </h4>
- </li>
- </ul>
- <ul className='nav nav__sub-menu padded'>
- <li>
- <a
- href='#'
- className={this.isSelected('logs')}
- onClick={this.handleClick.bind(this, 'logs', null)}
- >
- {'Logs'}
- </a>
- </li>
- </ul>
- </li>
- </ul>
+ <div className='nav-pills__container'>
+ <ul className='nav nav-pills nav-stacked'>
+ <li>
+ <ul className='nav nav__sub-menu'>
+ <li>
+ <h4>
+ <span className='icon fa fa-gear'></span>
+ <span>{'SETTINGS'}</span>
+ </h4>
+ </li>
+ </ul>
+ <ul className='nav nav__sub-menu padded'>
+ <li>
+ <a
+ href='#'
+ className={this.isSelected('service_settings')}
+ onClick={this.handleClick.bind(this, 'service_settings', null)}
+ >
+ {'Service Settings'}
+ </a>
+ </li>
+ <li>
+ <a
+ href='#'
+ className={this.isSelected('team_settings')}
+ onClick={this.handleClick.bind(this, 'team_settings', null)}
+ >
+ {'Team Settings'}
+ </a>
+ </li>
+ <li>
+ <a
+ href='#'
+ className={this.isSelected('sql_settings')}
+ onClick={this.handleClick.bind(this, 'sql_settings', null)}
+ >
+ {'SQL Settings'}
+ </a>
+ </li>
+ <li>
+ <a
+ href='#'
+ className={this.isSelected('email_settings')}
+ onClick={this.handleClick.bind(this, 'email_settings', null)}
+ >
+ {'Email Settings'}
+ </a>
+ </li>
+ <li>
+ <a
+ href='#'
+ className={this.isSelected('image_settings')}
+ onClick={this.handleClick.bind(this, 'image_settings', null)}
+ >
+ {'File Settings'}
+ </a>
+ </li>
+ <li>
+ <a
+ href='#'
+ className={this.isSelected('log_settings')}
+ onClick={this.handleClick.bind(this, 'log_settings', null)}
+ >
+ {'Log Settings'}
+ </a>
+ </li>
+ <li>
+ <a
+ href='#'
+ className={this.isSelected('rate_settings')}
+ onClick={this.handleClick.bind(this, 'rate_settings', null)}
+ >
+ {'Rate Limit Settings'}
+ </a>
+ </li>
+ <li>
+ <a
+ href='#'
+ className={this.isSelected('privacy_settings')}
+ onClick={this.handleClick.bind(this, 'privacy_settings', null)}
+ >
+ {'Privacy Settings'}
+ </a>
+ </li>
+ <li>
+ <a
+ href='#'
+ className={this.isSelected('gitlab_settings')}
+ onClick={this.handleClick.bind(this, 'gitlab_settings', null)}
+ >
+ {'GitLab Settings'}
+ </a>
+ </li>
+ </ul>
+ <ul className='nav nav__sub-menu'>
+ <li>
+ <h4>
+ <span className='icon fa fa-gear'></span>
+ <span>{'TEAMS (' + count + ')'}</span>
+ <span className='menu-icon--right'>
+ <a
+ href='#'
+ onClick={this.showTeamSelect}
+ >
+ <i className='fa fa-plus'></i>
+ </a>
+ </span>
+ </h4>
+ </li>
+ </ul>
+ <ul className='nav nav__sub-menu padded'>
+ <li>
+ {teams}
+ </li>
+ </ul>
+ <ul className='nav nav__sub-menu'>
+ <li>
+ <h4>
+ <span className='icon fa fa-gear'></span>
+ <span>{'OTHER'}</span>
+ </h4>
+ </li>
+ </ul>
+ <ul className='nav nav__sub-menu padded'>
+ <li>
+ <a
+ href='#'
+ className={this.isSelected('logs')}
+ onClick={this.handleClick.bind(this, 'logs', null)}
+ >
+ {'Logs'}
+ </a>
+ </li>
+ </ul>
+ </li>
+ </ul>
+ </div>
</div>
<SelectTeamModal
diff --git a/web/react/components/admin_console/email_settings.jsx b/web/react/components/admin_console/email_settings.jsx
index 762a4ab26..3432f69ff 100644
--- a/web/react/components/admin_console/email_settings.jsx
+++ b/web/react/components/admin_console/email_settings.jsx
@@ -437,7 +437,7 @@ export default class EmailSettings extends React.Component {
</select>
<div className='help-text'>
<table
- className='table-bordered'
+ className='table table-bordered'
cellPadding='5'
>
<tr><td className='help-text'>{'None'}</td><td className='help-text'>{'Mattermost will send email over an unsecure connection.'}</td></tr>
@@ -447,7 +447,7 @@ export default class EmailSettings extends React.Component {
</div>
<div className='help-text'>
<button
- className='help-link'
+ className='btn'
onClick={this.handleTestConnection}
disabled={!this.state.sendEmailNotifications}
id='connection-button'
@@ -482,7 +482,7 @@ export default class EmailSettings extends React.Component {
<p className='help-text'>{'32-character salt added to signing of email invites. Randomly generated on install. Click "Re-Generate" to create new salt.'}</p>
<div className='help-text'>
<button
- className='help-link'
+ className='btn'
onClick={this.handleGenerateInvite}
disabled={!this.state.sendEmailNotifications}
>
@@ -513,7 +513,7 @@ export default class EmailSettings extends React.Component {
<p className='help-text'>{'32-character salt added to signing of password reset emails. Randomly generated on install. Click "Re-Generate" to create new salt.'}</p>
<div className='help-text'>
<button
- className='help-link'
+ className='btn'
onClick={this.handleGenerateReset}
disabled={!this.state.sendEmailNotifications}
>
diff --git a/web/react/components/admin_console/image_settings.jsx b/web/react/components/admin_console/image_settings.jsx
index e52f516e8..e08d39ca8 100644
--- a/web/react/components/admin_console/image_settings.jsx
+++ b/web/react/components/admin_console/image_settings.jsx
@@ -460,7 +460,7 @@ export default class FileSettings extends React.Component {
<p className='help-text'>{'32-character salt added to signing of public image links. Randomly generated on install. Click "Re-Generate" to create new salt.'}</p>
<div className='help-text'>
<button
- className='help-link'
+ className='btn btn-default'
onClick={this.handleGenerate}
>
{'Re-Generate'}
diff --git a/web/react/components/admin_console/log_settings.jsx b/web/react/components/admin_console/log_settings.jsx
index 1c39c60e8..608ef9cc0 100644
--- a/web/react/components/admin_console/log_settings.jsx
+++ b/web/react/components/admin_console/log_settings.jsx
@@ -253,7 +253,7 @@ export default class LogSettings extends React.Component {
{'Format of log message output. If blank will be set to "[%D %T] [%L] %M", where:'}
<div className='help-text'>
<table
- className='table-bordered'
+ className='table table-bordered'
cellPadding='5'
>
<tr><td className='help-text'>{'%T'}</td><td className='help-text'>{'Time (15:04:05 MST)'}</td></tr>
diff --git a/web/react/components/email_verify.jsx b/web/react/components/email_verify.jsx
index 8d3f15525..391de3326 100644
--- a/web/react/components/email_verify.jsx
+++ b/web/react/components/email_verify.jsx
@@ -38,8 +38,8 @@ export default class EmailVerify extends React.Component {
}
return (
- <div className='col-sm-offset-4 col-sm-4'>
- <div className='panel panel-default'>
+ <div className='col-sm-12'>
+ <div className='panel panel-default verify_panel'>
<div className='panel-heading'>
<h3 className='panel-title'>{title}</h3>
</div>
diff --git a/web/react/components/get_link_modal.jsx b/web/react/components/get_link_modal.jsx
index 1d4aac3e6..6e0728862 100644
--- a/web/react/components/get_link_modal.jsx
+++ b/web/react/components/get_link_modal.jsx
@@ -23,7 +23,7 @@ export default class GetLinkModal extends React.Component {
componentDidMount() {
if (this.refs.modal) {
$(React.findDOMNode(this.refs.modal)).on('show.bs.modal', this.onShow);
- $(React.findDOMNode(this.refs.modal)).on('hide.bs.modal', this.onShow);
+ $(React.findDOMNode(this.refs.modal)).on('hide.bs.modal', this.onHide);
}
}
handleClick() {
@@ -43,8 +43,23 @@ export default class GetLinkModal extends React.Component {
}
render() {
var currentUser = UserStore.getCurrentUser();
- var copyLinkConfirm = null;
+ let copyLink = null;
+ if (document.queryCommandSupported('copy')) {
+ copyLink = (
+ <button
+ data-copy-btn='true'
+ type='button'
+ className='btn btn-primary pull-left'
+ onClick={this.handleClick}
+ data-clipboard-text={this.state.value}
+ >
+ Copy Link
+ </button>
+ );
+ }
+
+ var copyLinkConfirm = null;
if (this.state.copiedLink) {
copyLinkConfirm = <p className='alert alert-success copy-link-confirm'><i className='fa fa-check'></i> Link copied to clipboard.</p>;
}
@@ -98,15 +113,7 @@ export default class GetLinkModal extends React.Component {
>
Close
</button>
- <button
- data-copy-btn='true'
- type='button'
- className='btn btn-primary pull-left'
- onClick={this.handleClick}
- data-clipboard-text={this.state.value}
- >
- Copy Link
- </button>
+ {copyLink}
{copyLinkConfirm}
</div>
</div>
diff --git a/web/react/components/login.jsx b/web/react/components/login.jsx
index 70f7a5d6e..54df75cbc 100644
--- a/web/react/components/login.jsx
+++ b/web/react/components/login.jsx
@@ -112,6 +112,17 @@ export default class Login extends React.Component {
errorClass = ' has-error';
}
+ const verifiedParam = Utils.getUrlParameter('verified');
+ let verifiedBox = '';
+ if (verifiedParam) {
+ verifiedBox = (
+ <div className='alert alert-success'>
+ <i className='fa fa-check' />
+ {' Email Verified'}
+ </div>
+ );
+ }
+
let emailSignup;
if (global.window.config.EnableSignUpWithEmail === 'true') {
emailSignup = (
@@ -175,6 +186,7 @@ export default class Login extends React.Component {
<h2 className='signup-team__name'>{teamDisplayName}</h2>
<h2 className='signup-team__subdomain'>on {global.window.config.SiteName}</h2>
<form onSubmit={this.handleSubmit}>
+ {verifiedBox}
<div className={'form-group' + errorClass}>
{serverError}
</div>
diff --git a/web/react/components/signup_user_complete.jsx b/web/react/components/signup_user_complete.jsx
index ae3075495..4e17c6d06 100644
--- a/web/react/components/signup_user_complete.jsx
+++ b/web/react/components/signup_user_complete.jsx
@@ -20,8 +20,6 @@ export default class SignupUserComplete extends React.Component {
initialState.user = {};
initialState.user.team_id = this.props.teamId;
initialState.user.email = this.props.email;
- initialState.hash = this.props.hash;
- initialState.data = this.props.data;
initialState.original_email = this.props.email;
}
@@ -47,7 +45,7 @@ export default class SignupUserComplete extends React.Component {
return;
}
- const usernameError = Utils.isValidUsername(this.state.user.username);
+ const usernameError = Utils.isValidUsername(providedUsername);
if (usernameError === 'Cannot use a reserved word as a username.') {
this.setState({nameError: 'This username is reserved, please choose a new one.', emailError: '', passwordError: '', serverError: ''});
return;
@@ -67,26 +65,29 @@ export default class SignupUserComplete extends React.Component {
return;
}
+ const user = {
+ team_id: this.props.teamId,
+ email: providedEmail,
+ username: providedUsername,
+ password: providedPassword,
+ allow_marketing: true
+ };
+
this.setState({
- user: {
- email: providedEmail,
- username: providedUsername,
- password: providedPassword,
- allow_marketing: true
- },
+ user,
nameError: '',
emailError: '',
passwordError: '',
serverError: ''
});
- client.createUser(this.state.user, this.state.data, this.state.hash,
+ client.createUser(user, this.props.data, this.props.hash,
function createUserSuccess() {
client.track('signup', 'signup_user_02_complete');
- client.loginByEmail(this.props.teamName, this.state.user.email, this.state.user.password,
+ client.loginByEmail(this.props.teamName, user.email, user.password,
function emailLoginSuccess(data) {
- UserStore.setLastEmail(this.state.user.email);
+ UserStore.setLastEmail(user.email);
UserStore.setCurrentUser(data);
if (this.props.hash > 0) {
BrowserStore.setGlobalItem(this.props.hash, JSON.stringify({wizard: 'finished'}));
@@ -95,7 +96,7 @@ export default class SignupUserComplete extends React.Component {
}.bind(this),
function emailLoginFailure(err) {
if (err.message === 'Login failed because email address has not been verified') {
- window.location.href = '/verify_email?email=' + encodeURIComponent(this.state.user.email) + '&teamname=' + encodeURIComponent(this.props.teamName);
+ window.location.href = '/verify_email?email=' + encodeURIComponent(user.email) + '&teamname=' + encodeURIComponent(this.props.teamName);
} else {
this.setState({serverError: err.message});
}
diff --git a/web/react/components/user_settings/import_theme_modal.jsx b/web/react/components/user_settings/import_theme_modal.jsx
index 4e8ee03fa..3301c6596 100644
--- a/web/react/components/user_settings/import_theme_modal.jsx
+++ b/web/react/components/user_settings/import_theme_modal.jsx
@@ -49,7 +49,6 @@ export default class ImportThemeModal extends React.Component {
theme.sidebarText = colors[5];
theme.sidebarUnreadText = colors[5];
theme.sidebarTextHoverBg = colors[4];
- theme.sidebarTextHoverColor = colors[5];
theme.sidebarTextActiveBg = colors[2];
theme.sidebarTextActiveColor = colors[3];
theme.sidebarHeaderBg = colors[1];
diff --git a/web/react/package.json b/web/react/package.json
index 31295873b..a097b6aa8 100644
--- a/web/react/package.json
+++ b/web/react/package.json
@@ -10,7 +10,6 @@
"keymirror": "0.1.1",
"marked": "0.3.5",
"object-assign": "3.0.0",
- "react-zeroclipboard-mixin": "0.1.0",
"twemoji": "1.4.1"
},
"devDependencies": {
diff --git a/web/react/utils/constants.jsx b/web/react/utils/constants.jsx
index 67414dc3b..8fe1a5884 100644
--- a/web/react/utils/constants.jsx
+++ b/web/react/utils/constants.jsx
@@ -122,10 +122,9 @@ module.exports = {
default: {
type: 'Mattermost',
sidebarBg: '#fafafa',
- sidebarText: '#999999',
+ sidebarText: '#333333',
sidebarUnreadText: '#333333',
sidebarTextHoverBg: '#e6f2fa',
- sidebarTextHoverColor: '#999999',
sidebarTextActiveBg: '#e1e1e1',
sidebarTextActiveColor: '#111111',
sidebarHeaderBg: '#2389d7',
@@ -138,15 +137,15 @@ module.exports = {
newMessageSeparator: '#FF8800',
linkColor: '#2389d7',
buttonBg: '#2389d7',
- buttonColor: '#FFFFFF'
+ buttonColor: '#FFFFFF',
+ mentionHighlightBg: '#fff2bb'
},
organization: {
type: 'Organization',
sidebarBg: '#2071a7',
- sidebarText: '#bfcde8',
+ sidebarText: '#fff',
sidebarUnreadText: '#fff',
sidebarTextHoverBg: '#136197',
- sidebarTextHoverColor: '#bfcde8',
sidebarTextActiveBg: '#136197',
sidebarTextActiveColor: '#FFFFFF',
sidebarHeaderBg: '#2f81b7',
@@ -159,15 +158,15 @@ module.exports = {
newMessageSeparator: '#FF8800',
linkColor: '#2f81b7',
buttonBg: '#1dacfc',
- buttonColor: '#FFFFFF'
+ buttonColor: '#FFFFFF',
+ mentionHighlightBg: '#fff2bb'
},
mattermostDark: {
type: 'Mattermost Dark',
sidebarBg: '#1B2C3E',
- sidebarText: '#bbbbbb',
+ sidebarText: '#fff',
sidebarUnreadText: '#fff',
sidebarTextHoverBg: '#4A5664',
- sidebarTextHoverColor: '#bbbbbb',
sidebarTextActiveBg: '#39769C',
sidebarTextActiveColor: '#FFFFFF',
sidebarHeaderBg: '#1B2C3E',
@@ -180,15 +179,15 @@ module.exports = {
newMessageSeparator: '#5de5da',
linkColor: '#A4FFEB',
buttonBg: '#4CBBA4',
- buttonColor: '#FFFFFF'
+ buttonColor: '#FFFFFF',
+ mentionHighlightBg: '#338886'
},
windows10: {
type: 'Windows Dark',
sidebarBg: '#171717',
- sidebarText: '#eee',
+ sidebarText: '#fff',
sidebarUnreadText: '#fff',
sidebarTextHoverBg: '#302e30',
- sidebarTextHoverColor: '#fff',
sidebarTextActiveBg: '#484748',
sidebarTextActiveColor: '#FFFFFF',
sidebarHeaderBg: '#1f1f1f',
@@ -201,7 +200,8 @@ module.exports = {
newMessageSeparator: '#CC992D',
linkColor: '#0177e7',
buttonBg: '#0177e7',
- buttonColor: '#FFFFFF'
+ buttonColor: '#FFFFFF',
+ mentionHighlightBg: '#276198'
}
},
THEME_ELEMENTS: [
@@ -230,10 +230,6 @@ module.exports = {
uiName: 'Sidebar Text Hover BG'
},
{
- id: 'sidebarTextHoverColor',
- uiName: 'Sidebar Text Hover Color'
- },
- {
id: 'sidebarTextActiveBg',
uiName: 'Sidebar Text Active BG'
},
@@ -263,7 +259,7 @@ module.exports = {
},
{
id: 'newMessageSeparator',
- uiName: 'New message separator'
+ uiName: 'New Message Separator'
},
{
id: 'linkColor',
@@ -273,10 +269,13 @@ module.exports = {
id: 'buttonBg',
uiName: 'Button BG'
},
-
{
id: 'buttonColor',
uiName: 'Button Text'
+ },
+ {
+ id: 'mentionHighlightBg',
+ uiName: 'Mention Highlight BG'
}
]
};
diff --git a/web/react/utils/utils.jsx b/web/react/utils/utils.jsx
index 307a311ab..8431e56bc 100644
--- a/web/react/utils/utils.jsx
+++ b/web/react/utils/utils.jsx
@@ -399,9 +399,9 @@ export function applyTheme(theme) {
}
if (theme.sidebarText) {
- changeCss('.sidebar--left .nav-pills__container li>a, .sidebar--right, .settings-modal .nav-pills>li a, .sidebar--menu', 'color:' + theme.sidebarText, 1);
+ changeCss('.sidebar--left .nav-pills__container li>a, .sidebar--right, .settings-modal .nav-pills>li a, .sidebar--menu', 'color:' + changeOpacity(theme.sidebarText, 0.6), 1);
changeCss('@media(max-width: 768px){.settings-modal .settings-table .nav>li>a', 'color:' + theme.sidebarText, 1);
- changeCss('.sidebar--left .nav-pills__container li>h4, .sidebar--left .add-channel-btn', 'color:' + changeOpacity(theme.sidebarText, 0.8), 1);
+ changeCss('.sidebar--left .nav-pills__container li>h4, .sidebar--left .add-channel-btn', 'color:' + changeOpacity(theme.sidebarText, 0.6), 1);
changeCss('.sidebar--left .add-channel-btn:hover, .sidebar--left .add-channel-btn:focus', 'color:' + theme.sidebarText, 1);
changeCss('.sidebar--left, .sidebar--right .sidebar--right__header', 'border-color:' + changeOpacity(theme.sidebarText, 0.2), 1);
changeCss('.sidebar--left .status path', 'fill:' + changeOpacity(theme.sidebarText, 0.5), 1);
@@ -417,17 +417,13 @@ export function applyTheme(theme) {
changeCss('@media(max-width: 768px){.settings-modal .settings-table .nav>li:hover a', 'background:' + theme.sidebarTextHoverBg, 1);
}
- if (theme.sidebarTextHoverColor) {
- changeCss('.sidebar--left .nav-pills__container li>a:hover, .sidebar--left .nav-pills__container li>a:focus, .settings-modal .nav-pills>li:hover a, .settings-modal .nav-pills>li:focus a', 'color:' + theme.sidebarTextHoverColor, 2);
- changeCss('@media(max-width: 768px){.settings-modal .settings-table .nav>li:hover a', 'color:' + theme.sidebarTextHoverColor, 2);
- }
-
if (theme.sidebarTextActiveBg) {
changeCss('.sidebar--left .nav-pills__container li.active a, .sidebar--left .nav-pills__container li.active a:hover, .sidebar--left .nav-pills__container li.active a:focus, .settings-modal .nav-pills>li.active a, .settings-modal .nav-pills>li.active a:hover, .settings-modal .nav-pills>li.active a:active', 'background:' + theme.sidebarTextActiveBg, 1);
}
if (theme.sidebarTextActiveColor) {
changeCss('.sidebar--left .nav-pills__container li.active a, .sidebar--left .nav-pills__container li.active a:hover, .sidebar--left .nav-pills__container li.active a:focus, .settings-modal .nav-pills>li.active a, .settings-modal .nav-pills>li.active a:hover, .settings-modal .nav-pills>li.active a:active', 'color:' + theme.sidebarTextActiveColor, 2);
+ changeCss('.sidebar--left .nav-pills__container li.active a .status .online--icon', 'fill:' + theme.sidebarTextActiveColor, 2);
}
if (theme.sidebarHeaderBg) {
@@ -468,6 +464,7 @@ export function applyTheme(theme) {
changeCss('.date-separator .separator__text, .new-separator .separator__text', 'background:' + theme.centerChannelBg, 1);
changeCss('.post-image__column .post-image__details', 'background:' + theme.centerChannelBg, 1);
changeCss('.sidebar--right, .dropdown-menu, .popover', 'background:' + theme.centerChannelBg, 1);
+ changeCss('.search-bar__container .search__form .search-bar, .form-control', 'background:' + theme.centerChannelBg, 1);
}
if (theme.centerChannelColor) {
@@ -491,20 +488,21 @@ export function applyTheme(theme) {
changeCss('.post-image__column', 'border-color:' + changeOpacity(theme.centerChannelColor, 0.2), 2);
changeCss('.post-image__column .post-image__details', 'color:' + theme.centerChannelColor, 2);
changeCss('.post-image__column a, .post-image__column a:hover, .post-image__column a:focus', 'color:' + theme.centerChannelColor, 1);
- changeCss('.search-bar__container .search__form .search-bar', 'background: transparent; color:' + theme.centerChannelColor, 1);
+ changeCss('.search-bar__container .search__form .search-bar, .form-control', 'color:' + theme.centerChannelColor, 2);
changeCss('@media(max-width: 768px){.search-bar__container .search__form .search-bar', 'background:' + changeOpacity(theme.centerChannelColor, 0.2) + '; color: inherit;', 1);
- changeCss('.search-bar__container .search__form', 'border-color:' + changeOpacity(theme.centerChannelColor, 0.2), 1);
+ changeCss('.input-group-addon, .search-bar__container .search__form, .form-control', 'border-color:' + changeOpacity(theme.centerChannelColor, 0.2), 1);
+ changeCss('.form-control:focus', 'border-color:' + changeOpacity(theme.centerChannelColor, 0.3), 1);
changeCss('.channel-intro .channel-intro__content', 'background:' + changeOpacity(theme.centerChannelColor, 0.05), 1);
changeCss('.date-separator .separator__text', 'color:' + theme.centerChannelColor, 2);
changeCss('.date-separator .separator__hr, .modal-footer, .modal .custom-textarea, .post-right__container .post.post--root hr, .search-item-container', 'border-color:' + changeOpacity(theme.centerChannelColor, 0.2), 1);
changeCss('.modal .custom-textarea:focus', 'border-color:' + changeOpacity(theme.centerChannelColor, 0.3), 1);
changeCss('.channel-intro, .settings-modal .settings-table .settings-content .divider-dark, hr, .settings-modal .settings-table .settings-links', 'border-color:' + changeOpacity(theme.centerChannelColor, 0.2), 1);
changeCss('.post.current--user .post-body, .post.post--comment.other--root.current--user .post-comment', 'background:' + changeOpacity(theme.centerChannelColor, 0.07), 1);
- changeCss('.post.current--user .post-body, .post.post--comment.other--root.current--user .post-comment, .post.post--comment.other--root .post-comment, .post.same--root .post-body', 'border-color:' + changeOpacity(theme.centerChannelColor, 0.07), 2);
+ changeCss('.post.current--user .post-body, .post.post--comment.other--root.current--user .post-comment, .post.post--comment.other--root .post-comment, .post.same--root .post-body, .modal .more-channel-table tbody>tr td, .member-div:first-child, .member-div, .access-history__table .access__report, .activity-log__table', 'border-color:' + changeOpacity(theme.centerChannelColor, 0.1), 2);
changeCss('@media(max-width: 1440px){.post.same--root', 'border-color:' + changeOpacity(theme.centerChannelColor, 0.07), 2);
changeCss('@media(max-width: 1440px){.post.same--root', 'border-color:' + changeOpacity(theme.centerChannelColor, 0.07), 2);
changeCss('@media(max-width: 1800px){.inner__wrap.move--left .post.post--comment.same--root', 'border-color:' + changeOpacity(theme.centerChannelColor, 0.07), 2);
- changeCss('.post:hover, .sidebar--right .sidebar--right__header, .settings-modal .settings-table .settings-content .section-min:hover', 'background:' + changeOpacity(theme.centerChannelColor, 0.07), 1);
+ changeCss('.post:hover, .modal .more-channel-table tbody>tr:hover td, .sidebar--right .sidebar--right__header, .settings-modal .settings-table .settings-content .section-min:hover', 'background:' + changeOpacity(theme.centerChannelColor, 0.07), 1);
changeCss('.date-separator.hovered--before:after, .date-separator.hovered--after:before, .new-separator.hovered--after:before, .new-separator.hovered--before:after', 'background:' + changeOpacity(theme.centerChannelColor, 0.07), 1);
changeCss('.command-name:hover, .mentions-name:hover, .mentions-focus, .dropdown-menu>li>a:focus, .dropdown-menu>li>a:hover', 'background:' + changeOpacity(theme.centerChannelColor, 0.15), 1);
changeCss('.post.current--user:hover .post-body ', 'background: none;', 1);
@@ -529,6 +527,10 @@ export function applyTheme(theme) {
if (theme.buttonColor) {
changeCss('.btn.btn-primary', 'color:' + theme.buttonColor, 2);
}
+
+ if (theme.mentionHighlightBg) {
+ changeCss('.mention-highlight, .search-highlight', 'background:' + theme.mentionHighlightBg, 1);
+ }
}
export function changeCss(className, classValue, classRepeat) {
// we need invisible container to store additional css definitions
diff --git a/web/sass-files/sass/partials/_access-history.scss b/web/sass-files/sass/partials/_access-history.scss
index 412a2a1d0..a3289ecc0 100644
--- a/web/sass-files/sass/partials/_access-history.scss
+++ b/web/sass-files/sass/partials/_access-history.scss
@@ -24,6 +24,6 @@
font-size: 15px;
}
.report__info {
- color: #999;
+ @include opacity(0.8);
}
} \ No newline at end of file
diff --git a/web/sass-files/sass/partials/_activity-log.scss b/web/sass-files/sass/partials/_activity-log.scss
index 3f0c3090d..2fb37a3bb 100644
--- a/web/sass-files/sass/partials/_activity-log.scss
+++ b/web/sass-files/sass/partials/_activity-log.scss
@@ -1,3 +1,20 @@
+@keyframes highlight {
+ from { background: rgba(yellow, 0.5);}
+ to { background: none;}
+}
+
+.animation--highlight {
+ &:before {
+ content: '';
+ animation: highlight 1.5s ease;
+ position: absolute;
+ top: 0;
+ left: 0;
+ width: 100%;
+ height: 100%;
+ }
+}
+
.activity-log__table {
display: table;
width: 100%;
@@ -26,7 +43,7 @@
}
}
.report__info {
- color: #999;
+ @include opacity(0.8);
}
}
.session-help-text {
diff --git a/web/sass-files/sass/partials/_admin-console.scss b/web/sass-files/sass/partials/_admin-console.scss
index 5037da415..09907da6d 100644
--- a/web/sass-files/sass/partials/_admin-console.scss
+++ b/web/sass-files/sass/partials/_admin-console.scss
@@ -1,193 +1,202 @@
-
-.sidebar--left { &.sidebar--collapsable {
- background: #333;
- .team__header {
- background: transparent;
- margin-bottom: 5px;
- }
- .nav {
- li {
- padding: 0;
- .icon {
- width: 17px;
- }
- > a {
- color: #fff;
- padding: 9px 15px;
- display: block;
- &:hover, &.active, &:focus {
- background-color: $primary-color;
- }
- }
- > h4 {
- background: #333;
- padding: 10px 10px;
- margin: 1px 0 0;
- }
- }
- .menu-icon--right {
- vertical-align: top;
- padding: 5px 10px;
- margin: -5px;
- float: right;
- .fa {
- font-size: 13px;
- right: -2px;
- position: relative;
- color: #fff;
- }
+#admin_controller {
+ > div {
+ height: 100%;
+ }
+ .table {
+ background: #fff;
+ }
+ .sidebar--left {
+ &.sidebar--collapsable {
+ background: #333;
+ .team__header {
+ background: transparent;
+ margin-bottom: 5px;
}
- &.nav__sub-menu {
- background: #111;
- -webkit-font-smoothing: auto;
- &.padded {
- padding: 5px 0;
- }
+ .nav {
li {
+ padding: 0;
+ .icon {
+ width: 17px;
+ }
> a {
- font-size: 13px;
- padding: 5px 15px;
- background: transparent;
- color: #bbb;
- &:hover {
- color: lighten($primary-color, 10);
- }
- &.active {
- color: #fff;
- font-weight: 600;
+ padding: 9px 15px;
+ display: block;
+ &:hover, &.active, &:focus {
+ background-color: #EAEAEA;
}
}
- .nav-more {
+ > h4 {
+ background: #333;
+ padding: 10px 10px;
+ margin: 1px 0 0;
+ }
+ }
+ .menu-icon--right {
+ vertical-align: top;
+ padding: 5px 10px;
+ margin: -5px;
+ float: right;
+ .fa {
font-size: 13px;
- padding: 5px 15px;
- background: transparent;
- color: #bbb;
- display: block;
- cursor: pointer;
- &:hover {
- color: lighten($primary-color, 10);
+ right: -2px;
+ position: relative;
+ color: #fff;
+ }
+ }
+ &.nav__sub-menu {
+ background: #111;
+ -webkit-font-smoothing: auto;
+ &.padded {
+ padding: 5px 0;
+ }
+ li {
+ > a {
+ font-size: 13px;
+ padding: 5px 15px;
+ background: transparent;
+ color: #bbb;
+ &:hover {
+ color: lighten($primary-color, 10);
+ }
+ &.active {
+ color: #fff;
+ font-weight: 600;
+ }
+ }
+ .nav-more {
+ font-size: 13px;
+ padding: 5px 15px;
+ background: transparent;
+ color: #bbb;
+ display: block;
+ cursor: pointer;
+ &:hover {
+ color: lighten($primary-color, 10);
+ }
}
}
}
- }
- &.nav__inner-menu {
- li {
- > a {
- padding-left: 20px;
+ &.nav__inner-menu {
+ li {
+ > a {
+ padding-left: 20px;
+ }
}
}
}
}
}
-}
-.log__panel {
- overflow: scroll;
- width: 100%;
- height: 800px;
- border: 1px solid #ddd;
- margin-top: 10px;
- padding: 5px;
- background-color: white;
-}
-
-.app__content {
- &.admin {
- overflow: auto;
- background-color: #f1f1f1;
- padding: 0 20px 20px;
- min-height: 600px;
- }
- .wrapper--fixed {
- max-width: 800px;
+ .log__panel {
+ overflow: scroll;
+ width: 100%;
+ height: 800px;
+ border: 1px solid #ddd;
+ margin-top: 10px;
+ padding: 5px;
+ background-color: white;
}
- .form-horizontal {
- margin-top: 40px;
- .control-label {
- text-align: left;
- padding-right: 0;
- font-weight: 600;
+
+ .app__content {
+ &.admin {
+ overflow: auto;
+ background-color: #f1f1f1;
+ padding: 0 20px 20px;
+ min-height: 600px;
}
- .form-group {
- margin-bottom: 25px;
+ .wrapper--fixed {
+ max-width: 800px;
}
- .help-text {
- margin: 10px 0 0 15px;
- color: #777;
- .help-link {
- margin-right: 5px;
+ .form-horizontal {
+ margin-top: 40px;
+ .control-label {
+ text-align: left;
+ padding-right: 0;
+ font-weight: 600;
}
- .btn {
- font-size: 13px;
+ .form-group {
+ margin-bottom: 25px;
+ }
+ .help-text {
+ margin: 10px 0 0 15px;
+ color: #777;
+ .help-link {
+ margin-right: 5px;
+ }
+ .btn {
+ font-size: 13px;
+ }
+ }
+ .alert {
+ display: inline-block;
+ padding: 5px 7px;
+ margin: 1em 0 0;
+ top: 1px;
+ position: relative;
+ .fa {
+ margin-right: 5px;
+ }
}
}
- .alert {
- display: inline-block;
- padding: 5px 7px;
- margin: 0;
- top: 1px;
- position: relative;
- }
- }
- .banner {
- background: #fff;
- border: 1px solid #ddd;
- padding: 0.7em 1.5em;
- font-size: 0.95em;
- margin: 2em 0;
- .banner__heading {
- font-size: 1.5em;
+ .banner {
+ background: #fff;
+ border: 1px solid #ddd;
+ padding: 0.7em 1.5em;
+ font-size: 0.95em;
+ margin: 2em 0;
+ .banner__heading {
+ font-size: 1.5em;
+ }
+ .banner__content {
+ width: 80%;
+ }
}
- .banner__content {
- width: 80%;
+ .popover {
+ border-radius: 3px;
+ width: 100%;
+ font-size: 0.95em;
}
- }
- .popover {
- border-radius: 3px;
- width: 100%;
- font-size: 0.95em;
- }
- .panel {
- border: none;
- background-color: transparent;
- }
- .panel-default {
- > .panel-heading {
- padding: 10px 0;
+ .panel {
+ border: none;
background-color: transparent;
}
- .panel-body {
- padding: 30px 0 10px;
+ .panel-default {
+ > .panel-heading {
+ padding: 10px 0;
+ background-color: transparent;
+ }
+ .panel-body {
+ padding: 30px 0 10px;
+ }
+ }
+ .panel-group {
+ margin-bottom: 50px;
}
- }
- .panel-group {
- margin-bottom: 50px;
- }
- .panel-title {
- font-size: 24px;
- line-height: 1.5;
- a {
- text-decoration: none;
- display: block;
- @include clearfix;
- &.collapsed {
- .fa-minus {
- display: none;
+ .panel-title {
+ font-size: 24px;
+ line-height: 1.5;
+ a {
+ text-decoration: none;
+ display: block;
+ @include clearfix;
+ &.collapsed {
+ .fa-minus {
+ display: none;
+ }
+ .fa-plus {
+ display: inline-block;
+ }
+ }
+ .fa {
+ font-size: 18px;
+ float: right;
+ margin-top: 8px;
+ color: #aaa;
}
.fa-plus {
- display: inline-block;
+ display: none;
}
}
- .fa {
- font-size: 18px;
- float: right;
- margin-top: 8px;
- color: #aaa;
- }
- .fa-plus {
- display: none;
- }
}
}
-
} \ No newline at end of file
diff --git a/web/sass-files/sass/partials/_base.scss b/web/sass-files/sass/partials/_base.scss
index 841db7c5a..18462d92a 100644
--- a/web/sass-files/sass/partials/_base.scss
+++ b/web/sass-files/sass/partials/_base.scss
@@ -34,6 +34,10 @@ body {
}
}
+.input-group-addon {
+ background: transparent;
+}
+
.popover {
color: #333;
&.bottom {
@@ -97,6 +101,9 @@ a:focus, a:hover {
.form-control {
@include border-radius(2px);
+ &:focus {
+ @include box-shadow(none);
+ }
&.no-resize {
resize: none;
}
@@ -120,6 +127,10 @@ a:focus, a:hover {
z-index: 100;
}
+.nav>li>a:focus, .nav>li>a:hover {
+ background: transparent;
+}
+
.btn {
@include single-transition(all, 0.25s, ease-in);
@include border-radius(1px);
diff --git a/web/sass-files/sass/partials/_headers.scss b/web/sass-files/sass/partials/_headers.scss
index 2a4e82fc7..8e353aff9 100644
--- a/web/sass-files/sass/partials/_headers.scss
+++ b/web/sass-files/sass/partials/_headers.scss
@@ -37,7 +37,6 @@
&.description {
overflow: hidden;
text-overflow: ellipsis;
- @include opacity(0.6);
margin-top: 2px;
max-height: 45px;
}
diff --git a/web/sass-files/sass/partials/_mentions.scss b/web/sass-files/sass/partials/_mentions.scss
index a2bd0dcea..fb74eb4f5 100644
--- a/web/sass-files/sass/partials/_mentions.scss
+++ b/web/sass-files/sass/partials/_mentions.scss
@@ -57,5 +57,11 @@
.mention-highlight {
background-color:#fff2bb;
- color: #333;
+ a {
+ color: inherit;
+ text-decoration: underline;
+ &:hover, &:active {
+ color: inherit;
+ }
+ }
} \ No newline at end of file
diff --git a/web/sass-files/sass/partials/_modal.scss b/web/sass-files/sass/partials/_modal.scss
index 96b26f251..2722333a4 100644
--- a/web/sass-files/sass/partials/_modal.scss
+++ b/web/sass-files/sass/partials/_modal.scss
@@ -144,11 +144,10 @@
font-size: 0.9em;
overflow: hidden;
text-overflow: ellipsis;
- color: #999;
+ @include opacity(0.8);
margin: 5px 0;
}
.more-channel-name {
- color: #444;
font-weight: 600;
font-size: 0.95em;
}
diff --git a/web/sass-files/sass/partials/_post.scss b/web/sass-files/sass/partials/_post.scss
index 8bf4b0534..19cfdc050 100644
--- a/web/sass-files/sass/partials/_post.scss
+++ b/web/sass-files/sass/partials/_post.scss
@@ -257,7 +257,7 @@ body.ios {
line-height: 18px;
display: inline-block;
font-size: 13px;
- @include opacity(0.6);
+ @include opacity(0.7);
}
}
}
diff --git a/web/sass-files/sass/partials/_post_right.scss b/web/sass-files/sass/partials/_post_right.scss
index da5bcbad2..e4860b286 100644
--- a/web/sass-files/sass/partials/_post_right.scss
+++ b/web/sass-files/sass/partials/_post_right.scss
@@ -29,7 +29,7 @@
min-height: 100px;
}
.msg-typing {
- color: #555;
+ @include opacity(0.7);
float: left;
padding-top: 17px;
}
diff --git a/web/sass-files/sass/partials/_search.scss b/web/sass-files/sass/partials/_search.scss
index bcb8b5eac..a7b1ab190 100644
--- a/web/sass-files/sass/partials/_search.scss
+++ b/web/sass-files/sass/partials/_search.scss
@@ -104,7 +104,13 @@
padding: 10px;
}
-.search-highlight.theme, .search-highlight {
+.search-highlight {
background-color: #FFF2BB;
- color: #333;
+ a {
+ color: inherit;
+ text-decoration: underline;
+ &:hover, &:active {
+ color: inherit;
+ }
+ }
}
diff --git a/web/sass-files/sass/partials/_settings.scss b/web/sass-files/sass/partials/_settings.scss
index 42475efd5..9369cc097 100644
--- a/web/sass-files/sass/partials/_settings.scss
+++ b/web/sass-files/sass/partials/_settings.scss
@@ -240,10 +240,6 @@
margin-right:5px;
}
-.member-list-holder {
- background-color:#fff;
-}
-
.member-div {
border-bottom:1px solid lightgrey;
position:relative;
diff --git a/web/sass-files/sass/partials/_signup.scss b/web/sass-files/sass/partials/_signup.scss
index 924f0718a..fcf0d5d77 100644
--- a/web/sass-files/sass/partials/_signup.scss
+++ b/web/sass-files/sass/partials/_signup.scss
@@ -12,6 +12,9 @@
&.padding--less {
padding-top: 50px;
}
+ .form-control:focus {
+ @include box-shadow(inset 0 1px 1px rgba(0,0,0,.075),0 0 8px rgba(102,175,233,.6));
+ }
h1, h2, h3, h4, h5, h6, p {
line-height: 1.3;
@@ -330,3 +333,8 @@
.authorize-btn {
margin-right: 6px;
}
+
+.verify_panel {
+ margin: 60px auto auto auto;
+ max-width: 380px;
+}
diff --git a/web/templates/admin_console.html b/web/templates/admin_console.html
index 1444d9b17..a046478f6 100644
--- a/web/templates/admin_console.html
+++ b/web/templates/admin_console.html
@@ -5,15 +5,15 @@
{{template "head" . }}
<body>
-<div id="error_bar"></div>
+<div id='error_bar'></div>
-<div id="admin_controller"></div>
+<div id='admin_controller' class='container-fluid'></div>
-<div id="select_team_modal"></div>
+<div id='select_team_modal'></div>
<script>
window.setup_admin_console_page();
-
+
$(document).ready(function(){
$('[data-toggle="tooltip"]').tooltip();
$('[data-toggle="popover"]').popover();
diff --git a/web/templates/verify.html b/web/templates/verify.html
index cb4832512..a49ba7930 100644
--- a/web/templates/verify.html
+++ b/web/templates/verify.html
@@ -1,16 +1,21 @@
{{define "verify"}}
<!DOCTYPE html>
<html>
-{{template "head" . }}
-<body>
- <div class="container-fluid">
- <div class="row">
- <div id="verify"></div>
+ {{template "head" . }}
+ <body class="white">
+ <div class="container-fluid">
+ <div class="inner__wrap">
+ <div class="row content">
+ <div id="verify"></div>
+ </div>
+ <div class="row footer">
+ {{template "footer" . }}
+ </div>
+ </div>
</div>
- </div>
- <script>
- window.setupVerifyPage({{ .Props }});
- </script>
-</body>
+ <script>
+ window.setupVerifyPage({{ .Props }});
+ </script>
+ </body>
</html>
{{end}}
diff --git a/web/web.go b/web/web.go
index a1bbf5a81..b87636187 100644
--- a/web/web.go
+++ b/web/web.go
@@ -422,24 +422,17 @@ func verifyEmail(c *api.Context, w http.ResponseWriter, r *http.Request) {
}
}
- var isVerified string
- if len(userId) != 26 {
- isVerified = "false"
- } else if len(hashedId) == 0 {
- isVerified = "false"
- } else if model.ComparePassword(hashedId, userId) {
- isVerified = "true"
+ if len(userId) == 26 && len(hashedId) != 0 && model.ComparePassword(hashedId, userId) {
if c.Err = (<-api.Srv.Store.User().VerifyEmail(userId)).Err; c.Err != nil {
return
} else {
- c.LogAudit("")
+ c.LogAudit("Email Verified")
+ http.Redirect(w, r, api.GetProtocol(r)+"://"+r.Host+"/"+name+"/login?verified=true&email="+email, http.StatusTemporaryRedirect)
+ return
}
- } else {
- isVerified = "false"
}
page := NewHtmlTemplatePage("verify", "Email Verified")
- page.Props["IsVerified"] = isVerified
page.Props["TeamURL"] = c.GetTeamURLFromTeam(team)
page.Props["UserEmail"] = email
page.Props["ResendSuccess"] = resendSuccess