summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--utils/license.go2
-rw-r--r--webapp/components/analytics/system_analytics.jsx32
-rw-r--r--webapp/components/error_bar.jsx61
-rw-r--r--webapp/i18n/en.json8
-rw-r--r--webapp/sass/components/_error-bar.scss35
-rw-r--r--webapp/utils/constants.jsx2
-rw-r--r--webapp/utils/license_utils.jsx9
7 files changed, 93 insertions, 56 deletions
diff --git a/utils/license.go b/utils/license.go
index 2c43db6dd..5ec94386d 100644
--- a/utils/license.go
+++ b/utils/license.go
@@ -118,6 +118,7 @@ func getClientLicense(l *model.License) map[string]string {
props["IsLicensed"] = strconv.FormatBool(IsLicensed)
if IsLicensed {
+ props["Id"] = l.Id
props["Users"] = strconv.Itoa(*l.Features.Users)
props["LDAP"] = strconv.FormatBool(*l.Features.LDAP)
props["MFA"] = strconv.FormatBool(*l.Features.MFA)
@@ -166,6 +167,7 @@ func GetSanitizedClientLicense() map[string]string {
}
if IsLicensed {
+ delete(sanitizedLicense, "Id")
delete(sanitizedLicense, "Name")
delete(sanitizedLicense, "Email")
delete(sanitizedLicense, "PhoneNumber")
diff --git a/webapp/components/analytics/system_analytics.jsx b/webapp/components/analytics/system_analytics.jsx
index a3517899a..5af055924 100644
--- a/webapp/components/analytics/system_analytics.jsx
+++ b/webapp/components/analytics/system_analytics.jsx
@@ -1,7 +1,6 @@
// Copyright (c) 2016 Mattermost, Inc. All Rights Reserved.
// See License.txt for license information.
-import Banner from 'components/admin_console/banner.jsx';
import LineChart from './line_chart.jsx';
import DoughnutChart from './doughnut_chart.jsx';
import StatisticCount from './statistic_count.jsx';
@@ -9,7 +8,6 @@ import StatisticCount from './statistic_count.jsx';
import AnalyticsStore from 'stores/analytics_store.jsx';
import * as Utils from 'utils/utils.jsx';
-import {isLicenseExpired, isLicenseExpiring, displayExpiryDate} from 'utils/license_utils.jsx';
import * as AsyncClient from 'utils/async_client.jsx';
import Constants from 'utils/constants.jsx';
const StatTypes = Constants.StatTypes;
@@ -287,36 +285,6 @@ class SystemAnalytics extends React.Component {
{postTypeGraph}
</div>
);
-
- if (isLicenseExpired()) {
- banner = (
- <Banner
- description={
- <FormattedHTMLMessage
- id='analytics.system.expiredBanner'
- defaultMessage='The Enterprise license expired on {date}. You have 15 days from this date to renew the license, please contact <a href="mailto:commercial@mattermost.com">commercial@mattermost.com</a>.'
- values={{
- date: displayExpiryDate()
- }}
- />
- }
- />
- );
- } else if (isLicenseExpiring()) {
- banner = (
- <Banner
- description={
- <FormattedHTMLMessage
- id='analytics.system.expiringBanner'
- defaultMessage='The Enterprise license is expiring on {date}. To renew your license, please contact <a href="mailto:commercial@mattermost.com">commercial@mattermost.com</a>.'
- values={{
- date: displayExpiryDate()
- }}
- />
- }
- />
- );
- }
}
const userCount = (
diff --git a/webapp/components/error_bar.jsx b/webapp/components/error_bar.jsx
index 5fd12afc4..a1981aa2a 100644
--- a/webapp/components/error_bar.jsx
+++ b/webapp/components/error_bar.jsx
@@ -1,26 +1,37 @@
// Copyright (c) 2015 Mattermost, Inc. All Rights Reserved.
// See License.txt for license information.
+import AnalyticsStore from 'stores/analytics_store.jsx';
import ErrorStore from 'stores/error_store.jsx';
import UserStore from 'stores/user_store.jsx';
import * as Utils from 'utils/utils.jsx';
+import * as AsyncClient from 'utils/async_client.jsx';
import {isLicenseExpiring, isLicenseExpired, isLicensePastGracePeriod, displayExpiryDate} from 'utils/license_utils.jsx';
+import Constants from 'utils/constants.jsx';
+const StatTypes = Constants.StatTypes;
import React from 'react';
-import {FormattedMessage} from 'react-intl';
+import {FormattedMessage, FormattedHTMLMessage} from 'react-intl';
const EXPIRING_ERROR = 'error_bar.expiring';
const EXPIRED_ERROR = 'error_bar.expired';
const PAST_GRACE_ERROR = 'error_bar.past_grace';
+const RENEWAL_LINK = 'https://licensing.mattermost.com/renew';
+
+const BAR_DEVELOPER_TYPE = 'developer';
+const BAR_CRITICAL_TYPE = 'critical';
export default class ErrorBar extends React.Component {
constructor() {
super();
this.onErrorChange = this.onErrorChange.bind(this);
+ this.onAnalyticsChange = this.onAnalyticsChange.bind(this);
this.handleClose = this.handleClose.bind(this);
+ ErrorStore.clearNotificationError();
+
let isSystemAdmin = false;
const user = UserStore.getCurrentUser();
if (user) {
@@ -29,12 +40,16 @@ export default class ErrorBar extends React.Component {
if (!ErrorStore.getIgnoreNotification() && global.window.mm_config.SendEmailNotifications === 'false') {
ErrorStore.storeLastError({notification: true, message: Utils.localizeMessage('error_bar.preview_mode', 'Preview Mode: Email notifications have not been configured')});
+ } else if (isLicensePastGracePeriod()) {
+ if (isSystemAdmin) {
+ ErrorStore.storeLastError({notification: true, message: EXPIRED_ERROR, type: BAR_CRITICAL_TYPE});
+ } else {
+ ErrorStore.storeLastError({notification: true, message: PAST_GRACE_ERROR, type: BAR_CRITICAL_TYPE});
+ }
+ } else if (isLicenseExpired() && isSystemAdmin) {
+ ErrorStore.storeLastError({notification: true, message: EXPIRED_ERROR, type: BAR_CRITICAL_TYPE});
} else if (isLicenseExpiring() && isSystemAdmin) {
ErrorStore.storeLastError({notification: true, message: EXPIRING_ERROR});
- } else if (isLicenseExpired() && isSystemAdmin) {
- ErrorStore.storeLastError({notification: true, message: EXPIRED_ERROR, type: 'developer'});
- } else if (isLicensePastGracePeriod()) {
- ErrorStore.storeLastError({notification: true, message: PAST_GRACE_ERROR});
}
this.state = ErrorStore.getLastError();
@@ -49,27 +64,41 @@ export default class ErrorBar extends React.Component {
return false;
}
+ if (s.message === EXPIRING_ERROR && !this.state.totalUsers) {
+ return false;
+ }
+
return true;
}
componentDidMount() {
ErrorStore.addChangeListener(this.onErrorChange);
+ AnalyticsStore.addChangeListener(this.onAnalyticsChange);
}
componentWillUnmount() {
ErrorStore.removeChangeListener(this.onErrorChange);
+ AnalyticsStore.removeChangeListener(this.onAnalyticsChange);
}
onErrorChange() {
var newState = ErrorStore.getLastError();
if (newState) {
+ if (newState.message === EXPIRING_ERROR && !this.state.totalUsers) {
+ AsyncClient.getStandardAnalytics();
+ }
this.setState(newState);
} else {
this.setState({message: null});
}
}
+ onAnalyticsChange() {
+ const stats = AnalyticsStore.getAllSystem();
+ this.setState({totalUsers: stats[StatTypes.TOTAL_USERS]});
+ }
+
handleClose(e) {
if (e) {
e.preventDefault();
@@ -91,33 +120,41 @@ export default class ErrorBar extends React.Component {
var errClass = 'error-bar';
- if (this.state.type && this.state.type === 'developer') {
+ if (this.state.type === BAR_DEVELOPER_TYPE) {
errClass = 'error-bar-developer';
+ } else if (this.state.type === BAR_CRITICAL_TYPE) {
+ errClass = 'error-bar-critical';
}
+ const renewalLink = RENEWAL_LINK + '?id=' + global.window.mm_license.Id + '&user_count=' + this.state.totalUsers;
+
let message = this.state.message;
if (message === EXPIRING_ERROR) {
message = (
- <FormattedMessage
+ <FormattedHTMLMessage
id={EXPIRING_ERROR}
- defaultMessage='The Enterprise license is expiring on {date}. To renew your license, please contact commercial@mattermost.com'
+ defaultMessage='Enterprise license expires on {date}. <a href="{link}" target="_blank">Please renew.</a>'
values={{
- date: displayExpiryDate()
+ date: displayExpiryDate(),
+ link: renewalLink
}}
/>
);
} else if (message === EXPIRED_ERROR) {
message = (
- <FormattedMessage
+ <FormattedHTMLMessage
id={EXPIRED_ERROR}
- defaultMessage='Enterprise license has expired; you have 15 days from expiry to renew the license, please contact commercial@mattermost.com for details'
+ defaultMessage='Enterprise license is expired and some features may be disabled. <a href="{link}" target="_blank">Please renew.</a>'
+ values={{
+ link: renewalLink
+ }}
/>
);
} else if (message === PAST_GRACE_ERROR) {
message = (
<FormattedMessage
id={PAST_GRACE_ERROR}
- defaultMessage='Enterprise license has expired, please contact your System Administrator for details'
+ defaultMessage='Enterprise license is expired and some features may be disabled. Please contact your System Administrator for details.'
/>
);
}
diff --git a/webapp/i18n/en.json b/webapp/i18n/en.json
index 6841660cf..cf04ccc0e 100644
--- a/webapp/i18n/en.json
+++ b/webapp/i18n/en.json
@@ -941,8 +941,6 @@
"analytics.system.activeUsers": "Active Users With Posts",
"analytics.system.channelTypes": "Channel Types",
"analytics.system.dailyActiveUsers": "Daily Active Users",
- "analytics.system.expiredBanner": "The Enterprise license expired on {date}. You have 15 days from this date to renew the license, please contact <a href='mailto:commercial@mattermost.com'>commercial@mattermost.com</a>.",
- "analytics.system.expiringBanner": "The Enterprise license is expiring on {date}. To renew your license, please contact <a href='mailto:commercial@mattermost.com'>commercial@mattermost.com</a>.",
"analytics.system.monthlyActiveUsers": "Monthly Active Users",
"analytics.system.postTypes": "Posts, Files and Hashtags",
"analytics.system.privateGroups": "Private Groups",
@@ -1293,9 +1291,9 @@
"error.not_found.title": "Page not found",
"error.not_supported.message": "Private browsing is not supported",
"error.not_supported.title": "Browser not supported",
- "error_bar.expired": "Enterprise license has expired; you have 15 days from expiry to renew the license, please contact commercial@mattermost.com for details",
- "error_bar.expiring": "The Enterprise license is expiring on {date}. To renew your license, please contact commercial@mattermost.com",
- "error_bar.past_grace": "Enterprise license has expired, please contact your System Administrator for details",
+ "error_bar.expired": "Enterprise license is expired and some features may be disabled. <a href='{link}' target='_blank'>Please renew.</a>",
+ "error_bar.expiring": "Enterprise license expires on {date}. <a href='{link}' target='_blank'>Please renew.</a>",
+ "error_bar.past_grace": "Enterprise license is expired and some features may be disabled. Please contact your System Administrator for details.",
"error_bar.preview_mode": "Preview Mode: Email notifications have not been configured",
"file_attachment.download": "Download",
"file_info_preview.size": "Size ",
diff --git a/webapp/sass/components/_error-bar.scss b/webapp/sass/components/_error-bar.scss
index 2791337c4..c2ad2402a 100644
--- a/webapp/sass/components/_error-bar.scss
+++ b/webapp/sass/components/_error-bar.scss
@@ -11,6 +11,9 @@
z-index: 9999;
a {
+ color: $white !important;
+ text-decoration: underline;
+
&.error-bar__close {
color: $white;
font-family: 'Open Sans', sans-serif;
@@ -30,7 +33,7 @@
}
}
-.error-bar-developer {
+.error-bar-critical {
background-color: #B0171F;
color: white;
padding: 5px 30px;
@@ -59,3 +62,33 @@
}
}
}
+
+.error-bar-developer {
+ background-color: purple;
+ color: white;
+ padding: 5px 30px;
+ position: absolute;
+ text-align: center;
+ top: 0;
+ width: 100%;
+ z-index: 9999;
+
+ a {
+ &.error-bar__close {
+ color: $white;
+ font-family: 'Open Sans', sans-serif;
+ font-size: 20px;
+ font-weight: 600;
+ padding: 0 10px;
+ position: absolute;
+ right: 0;
+ text-decoration: none;
+ top: 0;
+
+ &:hover {
+ color: $white;
+ text-decoration: none;
+ }
+ }
+ }
+}
diff --git a/webapp/utils/constants.jsx b/webapp/utils/constants.jsx
index fafad9f44..cb55da9b8 100644
--- a/webapp/utils/constants.jsx
+++ b/webapp/utils/constants.jsx
@@ -885,8 +885,6 @@ export const Constants = {
BOT_NAME: 'BOT',
MAX_PREV_MSGS: 100,
POST_COLLAPSE_TIMEOUT: 1000 * 60 * 5, // five minutes
- LICENSE_EXPIRY_NOTIFICATION: 1000 * 60 * 60 * 24 * 15, // 15 days
- LICENSE_GRACE_PERIOD: 1000 * 60 * 60 * 24 * 15, // 15 days
PERMISSIONS_ALL: 'all',
PERMISSIONS_CHANNEL_ADMIN: 'channel_admin',
PERMISSIONS_TEAM_ADMIN: 'team_admin',
diff --git a/webapp/utils/license_utils.jsx b/webapp/utils/license_utils.jsx
index c4be1f25e..038e3ca29 100644
--- a/webapp/utils/license_utils.jsx
+++ b/webapp/utils/license_utils.jsx
@@ -1,17 +1,18 @@
// Copyright (c) 2016 Mattermost, Inc. All Rights Reserved.
// See License.txt for license information.
-import Constants from 'utils/constants.jsx';
-
import LocalizationStore from 'stores/localization_store.jsx';
+const LICENSE_EXPIRY_NOTIFICATION = 1000 * 60 * 60 * 24 * 60; // 60 days
+const LICENSE_GRACE_PERIOD = 1000 * 60 * 60 * 24 * 15; // 15 days
+
export function isLicenseExpiring() {
if (window.mm_license.IsLicensed !== 'true') {
return false;
}
const timeDiff = parseInt(global.window.mm_license.ExpiresAt, 10) - Date.now();
- return timeDiff <= Constants.LICENSE_EXPIRY_NOTIFICATION;
+ return timeDiff <= LICENSE_EXPIRY_NOTIFICATION;
}
export function isLicenseExpired() {
@@ -29,7 +30,7 @@ export function isLicensePastGracePeriod() {
}
const timeDiff = Date.now() - parseInt(global.window.mm_license.ExpiresAt, 10);
- return timeDiff > Constants.LICENSE_GRACE_PERIOD;
+ return timeDiff > LICENSE_GRACE_PERIOD;
}
export function displayExpiryDate() {