summaryrefslogtreecommitdiffstats
path: root/webapp
diff options
context:
space:
mode:
authorHarrison Healey <harrisonmhealey@gmail.com>2017-08-04 14:05:33 -0400
committerChristopher Speller <crspeller@gmail.com>2017-08-04 11:05:33 -0700
commitfb2022fb1cb3c8023efd22316d570d9b26facbd1 (patch)
treed70450ccfc3bfed2d10c6bfcb943ddda164d9882 /webapp
parent399865923658319d6d12a7719bc3b5554218bbad (diff)
downloadchat-fb2022fb1cb3c8023efd22316d570d9b26facbd1.tar.gz
chat-fb2022fb1cb3c8023efd22316d570d9b26facbd1.tar.bz2
chat-fb2022fb1cb3c8023efd22316d570d9b26facbd1.zip
PLT-6924 Added ability to disable file uploads/downloads on old mobile apps (#7117)
Diffstat (limited to 'webapp')
-rw-r--r--webapp/components/admin_console/storage_settings.jsx84
-rw-r--r--webapp/components/create_post.jsx3
-rw-r--r--webapp/components/file_attachment.jsx47
-rw-r--r--webapp/components/file_info_preview.jsx26
-rw-r--r--webapp/components/file_upload.jsx11
-rw-r--r--webapp/components/view_image.jsx29
-rw-r--r--webapp/components/view_image_popover_bar.jsx45
-rw-r--r--webapp/utils/file_utils.jsx24
8 files changed, 174 insertions, 95 deletions
diff --git a/webapp/components/admin_console/storage_settings.jsx b/webapp/components/admin_console/storage_settings.jsx
index 934a82f8f..4e0d9d19b 100644
--- a/webapp/components/admin_console/storage_settings.jsx
+++ b/webapp/components/admin_console/storage_settings.jsx
@@ -66,6 +66,53 @@ export default class StorageSettings extends AdminSettings {
}
renderSettings() {
+ const mobileUploadDownloadSettings = [];
+ if (window.mm_license.IsLicensed === 'true' && window.mm_license.Compliance === 'true') {
+ mobileUploadDownloadSettings.push(
+ <BooleanSetting
+ key='enableMobileUpload'
+ id='enableMobileUpload'
+ label={
+ <FormattedMessage
+ id='admin.file.enableMobileUploadTitle'
+ defaultMessage='Allow File Uploads on Mobile:'
+ />
+ }
+ helpText={
+ <FormattedMessage
+ id='admin.file.enableMobileUploadDesc'
+ defaultMessage='When false, disables file uploads on mobile apps. If Allow File Sharing is set to true, users can still upload files from a mobile web browser.'
+ />
+ }
+ value={this.state.enableMobileUpload}
+ onChange={this.handleChange}
+ disabled={!this.state.enableFileAttachments}
+ />
+ );
+
+ mobileUploadDownloadSettings.push(
+ <BooleanSetting
+ key='enableMobileDownload'
+ id='enableMobileDownload'
+ label={
+ <FormattedMessage
+ id='admin.file.enableMobileDownloadTitle'
+ defaultMessage='Allow File Downloads on Mobile:'
+ />
+ }
+ helpText={
+ <FormattedMessage
+ id='admin.file.enableMobileDownloadDesc'
+ defaultMessage='When false, disables file downloads on mobile apps. Users can still download files from a mobile web browser.'
+ />
+ }
+ value={this.state.enableMobileDownload}
+ onChange={this.handleChange}
+ disabled={!this.state.enableFileAttachments}
+ />
+ );
+ }
+
return (
<SettingsGroup>
<DropdownSetting
@@ -222,42 +269,7 @@ export default class StorageSettings extends AdminSettings {
value={this.state.enableFileAttachments}
onChange={this.handleChange}
/>
- <BooleanSetting
- id='enableMobileUpload'
- label={
- <FormattedMessage
- id='admin.file.enableMobileUploadTitle'
- defaultMessage='Allow File Uploads on Mobile:'
- />
- }
- helpText={
- <FormattedMessage
- id='admin.file.enableMobileUploadDesc'
- defaultMessage='When false, disables file uploads on mobile apps. If Allow File Sharing is set to true, users can still upload files from a mobile web browser.'
- />
- }
- value={this.state.enableMobileUpload}
- onChange={this.handleChange}
- disabled={!this.state.enableFileAttachments}
- />
- <BooleanSetting
- id='enableMobileDownload'
- label={
- <FormattedMessage
- id='admin.file.enableMobileDownloadTitle'
- defaultMessage='Allow File Downloads on Mobile:'
- />
- }
- helpText={
- <FormattedMessage
- id='admin.file.enableMobileDownloadDesc'
- defaultMessage='When false, disables file downloads on mobile apps. Users can still download files from a mobile web browser.'
- />
- }
- value={this.state.enableMobileDownload}
- onChange={this.handleChange}
- disabled={!this.state.enableFileAttachments}
- />
+ {mobileUploadDownloadSettings}
<TextSetting
id='maxFileSize'
label={
diff --git a/webapp/components/create_post.jsx b/webapp/components/create_post.jsx
index f822f46f4..55d6884ac 100644
--- a/webapp/components/create_post.jsx
+++ b/webapp/components/create_post.jsx
@@ -28,6 +28,7 @@ import TeamStore from 'stores/team_store.jsx';
import ConfirmModal from './confirm_modal.jsx';
import Constants from 'utils/constants.jsx';
+import * as FileUtils from 'utils/file_utils';
import {FormattedHTMLMessage, FormattedMessage} from 'react-intl';
import {browserHistory} from 'react-router/es6';
@@ -710,7 +711,7 @@ export default class CreatePost extends React.Component {
}
let attachmentsDisabled = '';
- if (global.window.mm_config.EnableFileAttachments === 'false') {
+ if (!FileUtils.canUploadFiles()) {
attachmentsDisabled = ' post-create--attachment-disabled';
}
diff --git a/webapp/components/file_attachment.jsx b/webapp/components/file_attachment.jsx
index 9459c44ef..3d7f936c8 100644
--- a/webapp/components/file_attachment.jsx
+++ b/webapp/components/file_attachment.jsx
@@ -1,15 +1,15 @@
// Copyright (c) 2015-present Mattermost, Inc. All Rights Reserved.
// See License.txt for license information.
-import Constants from 'utils/constants.jsx';
-import {getFileUrl, getFileThumbnailUrl} from 'mattermost-redux/utils/file_utils';
-import * as Utils from 'utils/utils.jsx';
-
+import PropTypes from 'prop-types';
+import React from 'react';
import {Tooltip, OverlayTrigger} from 'react-bootstrap';
-import PropTypes from 'prop-types';
+import Constants from 'utils/constants.jsx';
+import * as FileUtils from 'utils/file_utils';
+import * as Utils from 'utils/utils.jsx';
-import React from 'react';
+import {getFileUrl, getFileThumbnailUrl} from 'mattermost-redux/utils/file_utils';
export default class FileAttachment extends React.Component {
constructor(props) {
@@ -101,6 +101,8 @@ export default class FileAttachment extends React.Component {
trimmedFilename = fileName;
}
+ const canDownloadFiles = FileUtils.canDownloadFiles();
+
let filenameOverlay;
if (this.props.compactDisplay) {
filenameOverlay = (
@@ -124,7 +126,7 @@ export default class FileAttachment extends React.Component {
</a>
</OverlayTrigger>
);
- } else {
+ } else if (canDownloadFiles) {
filenameOverlay = (
<OverlayTrigger
trigger={['hover', 'focus']}
@@ -143,6 +145,27 @@ export default class FileAttachment extends React.Component {
</a>
</OverlayTrigger>
);
+ } else {
+ filenameOverlay = (
+ <span className='post-image__name'>
+ {trimmedFilename}
+ </span>
+ );
+ }
+
+ let downloadButton = null;
+ if (canDownloadFiles) {
+ downloadButton = (
+ <a
+ href={fileUrl}
+ download={fileName}
+ className='post-image__download'
+ target='_blank'
+ rel='noopener noreferrer'
+ >
+ <span className='fa fa-download'/>
+ </a>
+ );
}
return (
@@ -157,15 +180,7 @@ export default class FileAttachment extends React.Component {
<div className='post-image__details'>
{filenameOverlay}
<div>
- <a
- href={fileUrl}
- download={fileName}
- className='post-image__download'
- target='_blank'
- rel='noopener noreferrer'
- >
- <span className='fa fa-download'/>
- </a>
+ {downloadButton}
<span className='post-image__type'>{fileInfo.extension.toUpperCase()}</span>
<span className='post-image__size'>{Utils.fileSizeToString(fileInfo.size)}</span>
</div>
diff --git a/webapp/components/file_info_preview.jsx b/webapp/components/file_info_preview.jsx
index 4a90c4728..6032defb6 100644
--- a/webapp/components/file_info_preview.jsx
+++ b/webapp/components/file_info_preview.jsx
@@ -1,10 +1,10 @@
-import PropTypes from 'prop-types';
-
// Copyright (c) 2016-present Mattermost, Inc. All Rights Reserved.
// See License.txt for license information.
+import PropTypes from 'prop-types';
import React from 'react';
+import * as FileUtils from 'utils/file_utils';
import * as Utils from 'utils/utils.jsx';
export default class FileInfoPreview extends React.Component {
@@ -35,17 +35,31 @@ export default class FileInfoPreview extends React.Component {
const infoString = infoParts.join(', ');
- return (
- <div className='file-details__container'>
+ let preview = null;
+ if (FileUtils.canDownloadFiles()) {
+ preview = (
<a
- className={'file-details__preview'}
- to={fileUrl}
+ className='file-details__preview'
+ href={fileUrl}
target='_blank'
rel='noopener noreferrer'
>
<span className='file-details__preview-helper'/>
<img src={Utils.getFileIconPath(fileInfo)}/>
</a>
+ );
+ } else {
+ preview = (
+ <span className='file-details__preview'>
+ <span className='file-details__preview-helper'/>
+ <img src={Utils.getFileIconPath(fileInfo)}/>
+ </span>
+ );
+ }
+
+ return (
+ <div className='file-details__container'>
+ {preview}
<div className='file-details'>
<div className='file-details__name'>{fileInfo.name}</div>
<div className='file-details__info'>{infoString}</div>
diff --git a/webapp/components/file_upload.jsx b/webapp/components/file_upload.jsx
index 0eb12a097..3e28f11df 100644
--- a/webapp/components/file_upload.jsx
+++ b/webapp/components/file_upload.jsx
@@ -8,6 +8,7 @@ import Constants from 'utils/constants.jsx';
import ChannelStore from 'stores/channel_store.jsx';
import DelayedAction from 'utils/delayed_action.jsx';
import * as UserAgent from 'utils/user_agent.jsx';
+import * as FileUtils from 'utils/file_utils';
import * as Utils from 'utils/utils.jsx';
import {intlShape, injectIntl, defineMessages} from 'react-intl';
@@ -135,7 +136,7 @@ class FileUpload extends React.Component {
}
handleDrop(e) {
- if (global.window.mm_config.EnableFileAttachments === 'false') {
+ if (!FileUtils.canUploadFiles()) {
this.props.onUploadError(Utils.localizeMessage('file_upload.disabled', 'File attachments are disabled.'));
return;
}
@@ -172,7 +173,7 @@ class FileUpload extends React.Component {
});
let dragsterActions = {};
- if (global.window.mm_config.EnableFileAttachments === 'true') {
+ if (FileUtils.canUploadFiles()) {
dragsterActions = {
enter(dragsterEvent, e) {
var files = e.originalEvent.dataTransfer;
@@ -263,7 +264,7 @@ class FileUpload extends React.Component {
// This looks redundant, but must be done this way due to
// setState being an asynchronous call
if (items && items.length > 0) {
- if (global.window.mm_config.EnableFileAttachments === 'false') {
+ if (!FileUtils.canUploadFiles()) {
this.props.onUploadError(Utils.localizeMessage('file_upload.disabled', 'File attachments are disabled.'));
return;
}
@@ -326,7 +327,7 @@ class FileUpload extends React.Component {
if (Utils.cmdOrCtrlPressed(e) && e.keyCode === Constants.KeyCodes.U) {
e.preventDefault();
- if (global.window.mm_config.EnableFileAttachments === 'false') {
+ if (!FileUtils.canUploadFiles()) {
this.props.onUploadError(Utils.localizeMessage('file_upload.disabled', 'File attachments are disabled.'));
return;
}
@@ -377,7 +378,7 @@ class FileUpload extends React.Component {
const uploadsRemaining = Constants.MAX_UPLOAD_FILES - this.props.getFileCount(channelId);
let fileDiv;
- if (global.window.mm_config.EnableFileAttachments === 'true') {
+ if (FileUtils.canUploadFiles()) {
fileDiv = (
<div className='icon--attachment'>
<span
diff --git a/webapp/components/view_image.jsx b/webapp/components/view_image.jsx
index 237d0a6dc..4350711fc 100644
--- a/webapp/components/view_image.jsx
+++ b/webapp/components/view_image.jsx
@@ -1,24 +1,25 @@
// Copyright (c) 2015-present Mattermost, Inc. All Rights Reserved.
// See License.txt for license information.
-import AudioVideoPreview from './audio_video_preview.jsx';
-import CodePreview from './code_preview.jsx';
-import PDFPreview from './pdf_preview.jsx';
-import FileInfoPreview from './file_info_preview.jsx';
-import ViewImagePopoverBar from './view_image_popover_bar.jsx';
+import $ from 'jquery';
+import PropTypes from 'prop-types';
+import React from 'react';
+import {Modal} from 'react-bootstrap';
import * as GlobalActions from 'actions/global_actions.jsx';
+import * as FileUtils from 'utils/file_utils';
import * as Utils from 'utils/utils.jsx';
-import {getFileUrl, getFilePreviewUrl} from 'mattermost-redux/utils/file_utils';
-import Constants from 'utils/constants.jsx';
-const KeyCodes = Constants.KeyCodes;
+import {KeyCodes} from 'utils/constants.jsx';
-import $ from 'jquery';
-import PropTypes from 'prop-types';
-import React from 'react';
-import {Modal} from 'react-bootstrap';
+import {getFileUrl, getFilePreviewUrl} from 'mattermost-redux/utils/file_utils';
+
+import AudioVideoPreview from './audio_video_preview.jsx';
+import CodePreview from './code_preview.jsx';
+import FileInfoPreview from './file_info_preview.jsx';
+import PDFPreview from './pdf_preview.jsx';
+import ViewImagePopoverBar from './view_image_popover_bar.jsx';
import loadingGif from 'images/load.gif';
@@ -350,6 +351,10 @@ function ImagePreview({fileInfo, fileUrl}) {
previewUrl = fileUrl;
}
+ if (!FileUtils.canDownloadFiles()) {
+ return <img src={previewUrl}/>;
+ }
+
return (
<a
href={fileUrl}
diff --git a/webapp/components/view_image_popover_bar.jsx b/webapp/components/view_image_popover_bar.jsx
index 88055b47b..6a092cbbe 100644
--- a/webapp/components/view_image_popover_bar.jsx
+++ b/webapp/components/view_image_popover_bar.jsx
@@ -1,13 +1,13 @@
// Copyright (c) 2015-present Mattermost, Inc. All Rights Reserved.
// See License.txt for license information.
-import {FormattedMessage} from 'react-intl';
-
import PropTypes from 'prop-types';
-
import React from 'react';
+import {FormattedMessage} from 'react-intl';
+
+import * as FileUtils from 'utils/file_utils';
-export default class ViewImagePopoverBar extends React.Component {
+export default class ViewImagePopoverBar extends React.PureComponent {
render() {
var publicLink = '';
if (global.window.mm_config.EnablePublicLink === 'true') {
@@ -34,21 +34,9 @@ export default class ViewImagePopoverBar extends React.Component {
footerClass += ' footer--show';
}
- return (
- <div
- ref='imageFooter'
- className={footerClass}
- >
- <span className='pull-left text'>
- <FormattedMessage
- id='view_image_popover.file'
- defaultMessage='File {count, number} of {total, number}'
- values={{
- count: (this.props.fileId + 1),
- total: this.props.totalFiles
- }}
- />
- </span>
+ let downloadLinks = null;
+ if (FileUtils.canDownloadFiles()) {
+ downloadLinks = (
<div className='image-links'>
{publicLink}
<a
@@ -64,6 +52,25 @@ export default class ViewImagePopoverBar extends React.Component {
/>
</a>
</div>
+ );
+ }
+
+ return (
+ <div
+ ref='imageFooter'
+ className={footerClass}
+ >
+ <span className='pull-left text'>
+ <FormattedMessage
+ id='view_image_popover.file'
+ defaultMessage='File {count, number} of {total, number}'
+ values={{
+ count: (this.props.fileId + 1),
+ total: this.props.totalFiles
+ }}
+ />
+ </span>
+ {downloadLinks}
</div>
);
}
diff --git a/webapp/utils/file_utils.jsx b/webapp/utils/file_utils.jsx
new file mode 100644
index 000000000..42feb11be
--- /dev/null
+++ b/webapp/utils/file_utils.jsx
@@ -0,0 +1,24 @@
+// Copyright (c) 2017-present Mattermost, Inc. All Rights Reserved.
+// See License.txt for license information.
+
+import * as UserAgent from 'utils/user_agent';
+
+export function canUploadFiles() {
+ if (window.mm_config.EnableFileAttachments === 'false') {
+ return false;
+ }
+
+ if (UserAgent.isMobileApp() && window.mm_license.IsLicensed === 'true' && window.mm_license.Compliance === 'true') {
+ return window.mm_config.EnableMobileFileUpload !== 'false';
+ }
+
+ return true;
+}
+
+export function canDownloadFiles() {
+ if (UserAgent.isMobileApp() && window.mm_license.IsLicensed === 'true' && window.mm_license.Compliance === 'true') {
+ return window.mm_config.EnableMobileFileDownload !== 'false';
+ }
+
+ return true;
+}