Files
mattermost/webapp/components/admin_console/license_settings.jsx
Corey Hulen 2e5617c29b PLT-2057 User as a first class object (#2648)
* Adding TeamMember to system

* Fixing all unit tests on the backend

* Fixing merge conflicts

* Fixing merge conflict

* Adding javascript unit tests

* Adding TeamMember to system

* Fixing all unit tests on the backend

* Fixing merge conflicts

* Fixing merge conflict

* Adding javascript unit tests

* Adding client side unit test

* Cleaning up the clint side tests

* Fixing msg

* Adding more client side unit tests

* Adding more using tests

* Adding last bit of client side unit tests and adding make cmd

* Fixing bad merge

* Fixing libraries

* Updating to new client side API

* Fixing borken unit test

* Fixing unit tests

* ugg...trying to beat gofmt

* ugg...trying to beat gofmt

* Cleaning up remainder of the server side routes

* Adding inital load api

* Increased coverage of webhook unit tests (#2660)

* Adding loading ... to root html

* Fixing bad merge

* Removing explicit content type so superagent will guess corectly (#2685)

* Fixing merge and unit tests

* Adding create team UI

* Fixing signup flows

* Adding LDAP unit tests and enterprise unit test helper (#2702)

* Add the ability to reset MFA from the commandline (#2706)

* Fixing compliance unit tests

* Fixing client side tests

* Adding open server to system console

* Moving websocket connection

* Fixing unit test

* Fixing unit tests

* Fixing unit tests

* Adding nickname and more LDAP unit tests (#2717)

* Adding join open teams

* Cleaning up all TODOs in the code

* Fixing web sockets

* Removing unused webockets file

* PLT-2533 Add the ability to reset a user's MFA from the system console (#2715)

* Add the ability to reset a user's MFA from the system console

* Add client side unit test for adminResetMfa

* Reorganizing authentication to fix LDAP error message (#2723)

* Fixing failing unit test

* Initial upgrade db code

* Adding upgrade script

* Fixing upgrade script after running on core

* Update OAuth and Claim routes to work with user model changes (#2739)

* Fixing perminant deletion. Adding ability to delete all user and the entire database (#2740)

* Fixing team invite ldap login call (#2741)

* Fixing bluebar and some img stuff

* Fix all the different file upload web utils (#2743)

* Fixing invalid session redirect (#2744)

* Redirect on bad channel name (#2746)

* Fixing a bunch of issue and removing dead code

* Patch to fix error message on leave channel (#2747)

* Setting EnableOpenServer to false by default

* Fixing config

* Fixing upgrade

* Fixing reported bugs

* Bug fixes for PLT-2057

* PLT-2563 Redo password recovery to use a database table (#2745)

* Redo password recovery to use a database table

* Update reset password audits

* Split out admin and user reset password APIs to be separate

* Delete password recovery when user is permanently deleted

* Consolidate password resetting into a single function

* Removed private channels as an option for outgoing webhooks (#2752)

* PLT-2577/PLT-2552 Fixes for backstage (#2753)

* Added URL to incoming webhook list

* Fixed client functions for adding/removing integrations

* Disallowed slash commands without trigger words

* Fixed clientside handling of errors on AddCommand page

* Minor auth cleanup (#2758)

* Changed EditPostModal to just close if you save without making any changes (#2759)

* Renamed client -> Client in async_client.jsx and fixed eslint warnings (#2756)

* Fixed url in channel info modal (#2755)

* Fixing reported issues

* Moving to version 3 of the apis

* Fixing command unit tests (#2760)

* Adding team admins

* Fixing DM issue

* Fixing eslint error

* Properly set EditPostModal's originalText state in all cases (#2762)

* Update client config check to assume features is defined if server is licensed (#2772)

* Fixing url link

* Fixing issue with websocket crashing when sending messages to different teams
2016-04-21 22:37:01 -07:00

280 lines
11 KiB
JavaScript

// Copyright (c) 2015 Mattermost, Inc. All Rights Reserved.
// See License.txt for license information.
import $ from 'jquery';
import ReactDOM from 'react-dom';
import * as Utils from 'utils/utils.jsx';
import Client from 'utils/web_client.jsx';
import {injectIntl, intlShape, defineMessages, FormattedMessage, FormattedHTMLMessage} from 'react-intl';
const holders = defineMessages({
removing: {
id: 'admin.license.removing',
defaultMessage: 'Removing License...'
},
uploading: {
id: 'admin.license.uploading',
defaultMessage: 'Uploading License...'
}
});
import React from 'react';
class LicenseSettings extends React.Component {
constructor(props) {
super(props);
this.handleChange = this.handleChange.bind(this);
this.handleSubmit = this.handleSubmit.bind(this);
this.handleRemove = this.handleRemove.bind(this);
this.state = {
fileSelected: false,
fileName: null,
serverError: null
};
}
handleChange() {
const element = $(ReactDOM.findDOMNode(this.refs.fileInput));
if (element.prop('files').length > 0) {
this.setState({fileSelected: true, fileName: element.prop('files')[0].name});
}
}
handleSubmit(e) {
e.preventDefault();
const element = $(ReactDOM.findDOMNode(this.refs.fileInput));
if (element.prop('files').length === 0) {
return;
}
const file = element.prop('files')[0];
$('#upload-button').button('loading');
Client.uploadLicenseFile(file,
() => {
Utils.clearFileInput(element[0]);
$('#upload-button').button('reset');
this.setState({fileSelected: false, fileName: null, serverError: null});
window.location.reload(true);
},
(error) => {
Utils.clearFileInput(element[0]);
$('#upload-button').button('reset');
this.setState({fileSelected: false, fileName: null, serverError: error.message});
}
);
}
handleRemove(e) {
e.preventDefault();
$('#remove-button').button('loading');
Client.removeLicenseFile(
() => {
$('#remove-button').button('reset');
this.setState({fileSelected: false, fileName: null, serverError: null});
window.location.reload(true);
},
(error) => {
$('#remove-button').button('reset');
this.setState({fileSelected: false, fileName: null, serverError: error.message});
}
);
}
render() {
var serverError = '';
if (this.state.serverError) {
serverError = <div className='form-group has-error'><label className='control-label'>{this.state.serverError}</label></div>;
}
var btnClass = 'btn';
if (this.state.fileSelected) {
btnClass = 'btn btn-primary';
}
let edition;
let licenseType;
let licenseKey;
const issued = Utils.displayDate(parseInt(global.window.mm_license.IssuedAt, 10)) + ' ' + Utils.displayTime(parseInt(global.window.mm_license.IssuedAt, 10), true);
const startsAt = Utils.displayDate(parseInt(global.window.mm_license.StartsAt, 10));
const expiresAt = Utils.displayDate(parseInt(global.window.mm_license.ExpiresAt, 10));
if (global.window.mm_license.IsLicensed === 'true') {
// Note: DO NOT LOCALISE THESE STRINGS. Legally we can not since the license is in English.
edition = 'Mattermost Enterprise Edition. Enterprise features on this server have been unlocked with a license key and a valid subscription.';
licenseType = (
<div>
<p>
{'This software is offered under a commercial license.\n\nSee ENTERPRISE-EDITION-LICENSE.txt in your root install directory for details. See NOTICE.txt for information about open source software used in this system.\n\nYour subscription details are as follows:'}
</p>
{`Name: ${global.window.mm_license.Name}`}<br/>
{`Company or organization name: ${global.window.mm_license.Company}`}<br/>
{`Number of users: ${global.window.mm_license.Users}`}<br/>
{`License issued: ${issued}`}<br/>
{`Start date of license: ${startsAt}`}<br/>
{`Expiry date of license: ${expiresAt}`}<br/>
<br/>
{'See also '}<a href='https://about.mattermost.com/enterprise-edition-terms/'>{'Enterprise Edition Terms of Service'}</a>{' and '}<a href='https://about.mattermost.com/privacy/'>{'Privacy Policy.'}</a>
</div>
);
licenseKey = (
<div className='col-sm-8'>
<button
className='btn btn-danger'
onClick={this.handleRemove}
id='remove-button'
data-loading-text={'<span class=\'glyphicon glyphicon-refresh glyphicon-refresh-animate\'></span> ' + this.props.intl.formatMessage(holders.removing)}
>
<FormattedMessage
id='admin.license.keyRemove'
defaultMessage='Remove Enterprise License and Downgrade Server'
/>
</button>
<br/>
<br/>
<p className='help-text'>
{'If you migrate servers you may need to remove your license key to install it elsewhere. You can remove the key here, which will revert functionality to that of Team Edition.'}
</p>
</div>
);
} else {
// Note: DO NOT LOCALISE THESE STRINGS. Legally we can not since the license is in English.
edition = (
<p>
{'Mattermost Enterprise Edition. Unlock enterprise features in this software through the purchase of a subscription from '}
<a
target='_blank'
href='https://mattermost.com/'
>
{'https://mattermost.com/'}
</a>
</p>
);
licenseType = 'This software is offered under a commercial license.\n\nSee ENTERPRISE-EDITION-LICENSE.txt in your root install directory for details. See NOTICE.txt for information about open source software used in this system.';
let fileName;
if (this.state.fileName) {
fileName = this.state.fileName;
} else {
fileName = (
<FormattedMessage
id='admin.license.noFile'
defaultMessage='No file uploaded'
/>
);
}
licenseKey = (
<div className='col-sm-8'>
<div className='file__upload'>
<button className='btn btn-primary'>
<FormattedMessage
id='admin.license.choose'
defaultMessage='Choose File'
/>
</button>
<input
ref='fileInput'
type='file'
accept='.mattermost-license'
onChange={this.handleChange}
/>
</div>
<button
className={btnClass}
disabled={!this.state.fileSelected}
onClick={this.handleSubmit}
id='upload-button'
data-loading-text={'<span class=\'glyphicon glyphicon-refresh glyphicon-refresh-animate\'></span> ' + this.props.intl.formatMessage(holders.uploading)}
>
<FormattedMessage
id='admin.license.upload'
defaultMessage='Upload'
/>
</button>
<div className='help-text no-margin'>
{fileName}
</div>
<br/>
{serverError}
<p className='help-text no-margin'>
<FormattedHTMLMessage
id='admin.license.uploadDesc'
defaultMessage='Upload a license key for Mattermost Enterprise Edition to upgrade this server. <a href="http://mattermost.com" target="_blank">Visit us online</a> to learn more about the benefits of Enterprise Edition or to purchase a key.'
/>
</p>
</div>
);
}
return (
<div className='wrapper--fixed'>
<h3>
<FormattedMessage
id='admin.license.title'
defaultMessage='Edition and License'
/>
</h3>
<form
className='form-horizontal'
role='form'
>
<div className='form-group'>
<label
className='control-label col-sm-4'
>
<FormattedMessage
id='admin.license.edition'
defaultMessage='Edition: '
/>
</label>
<div className='col-sm-8'>
{edition}
</div>
</div>
<div className='form-group'>
<label
className='control-label col-sm-4'
>
<FormattedMessage
id='admin.license.type'
defaultMessage='License: '
/>
</label>
<div className='col-sm-8'>
{licenseType}
</div>
</div>
<div className='form-group'>
<label
className='control-label col-sm-4'
>
<FormattedMessage
id='admin.license.key'
defaultMessage='License Key: '
/>
</label>
{licenseKey}
</div>
</form>
</div>
);
}
}
LicenseSettings.propTypes = {
intl: intlShape.isRequired,
config: React.PropTypes.object
};
export default injectIntl(LicenseSettings);