update list of mime types and move to common server and client file (#511)

Fixes #476 and fixes #450
This commit is contained in:
Cassie Tarakajian 2018-02-01 16:45:19 -05:00 committed by GitHub
parent c50f64c0f3
commit 6cd71acb81
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
5 changed files with 294 additions and 539 deletions

View file

@ -3,6 +3,7 @@ import Dropzone from 'dropzone';
import { bindActionCreators } from 'redux'; import { bindActionCreators } from 'redux';
import { connect } from 'react-redux'; import { connect } from 'react-redux';
import * as UploaderActions from '../actions/uploader'; import * as UploaderActions from '../actions/uploader';
import { fileExtensionsAndMimeTypes } from '../../../../server/utils/fileUtils';
const s3Bucket = process.env.S3_BUCKET_URL_BASE || const s3Bucket = process.env.S3_BUCKET_URL_BASE ||
`https://s3-${process.env.AWS_REGION}.amazonaws.com/${process.env.S3_BUCKET}/`; `https://s3-${process.env.AWS_REGION}.amazonaws.com/${process.env.S3_BUCKET}/`;
@ -26,11 +27,7 @@ class FileUploader extends React.Component {
maxThumbnailFilesize: 8, // 8 mb maxThumbnailFilesize: 8, // 8 mb
thumbnailWidth: 200, thumbnailWidth: 200,
thumbnailHeight: 200, thumbnailHeight: 200,
// TODO what is a good list of MIME types???? acceptedFiles: fileExtensionsAndMimeTypes,
acceptedFiles: `image/*,audio/*,text/javascript,text/html,text/css,
application/json,application/x-font-ttf,application/x-font-truetype,
text/plain,text/csv,.obj,video/webm,video/ogg,video/quicktime,video/mp4,
.otf,.ttf`,
dictDefaultMessage: 'Drop files here to upload or click to use the file browser', dictDefaultMessage: 'Drop files here to upload or click to use the file browser',
accept: this.props.dropzoneAcceptCallback.bind(this, userId), accept: this.props.dropzoneAcceptCallback.bind(this, userId),
sending: this.props.dropzoneSendingCallback, sending: this.props.dropzoneSendingCallback,

View file

@ -7,18 +7,18 @@ import loopProtect from 'loop-protect';
import { JSHINT } from 'jshint'; import { JSHINT } from 'jshint';
import { getBlobUrl } from '../actions/files'; import { getBlobUrl } from '../actions/files';
import { resolvePathToFile } from '../../../../server/utils/filePath'; import { resolvePathToFile } from '../../../../server/utils/filePath';
import {
MEDIA_FILE_REGEX,
MEDIA_FILE_QUOTED_REGEX,
STRING_REGEX,
TEXT_FILE_REGEX,
EXTERNAL_LINK_REGEX,
NOT_EXTERNAL_LINK_REGEX
} from '../../../../server/utils/fileUtils';
const decomment = require('decomment'); const decomment = require('decomment');
const startTag = '@fs-'; const startTag = '@fs-';
// eslint-disable-next-line max-len
const MEDIA_FILE_REGEX = /^('|")(?!(http:\/\/|https:\/\/)).*\.(png|jpg|jpeg|gif|bmp|mp3|wav|aiff|ogg|json|txt|csv|svg|obj|mp4|ogg|webm|mov|otf|ttf|m4a)('|")$/i;
// eslint-disable-next-line max-len
const MEDIA_FILE_REGEX_NO_QUOTES = /^(?!(http:\/\/|https:\/\/)).*\.(png|jpg|jpeg|gif|bmp|mp3|wav|aiff|ogg|json|txt|csv|svg|obj|mp4|ogg|webm|mov|otf|ttf|m4a)$/i;
const STRING_REGEX = /(['"])((\\\1|.)*?)\1/gm;
const TEXT_FILE_REGEX = /(.+\.json$|.+\.txt$|.+\.csv$)/i;
const NOT_EXTERNAL_LINK_REGEX = /^(?!(http:\/\/|https:\/\/))/;
const EXTERNAL_LINK_REGEX = /^(http:\/\/|https:\/\/)/;
function getAllScriptOffsets(htmlFile) { function getAllScriptOffsets(htmlFile) {
const offs = []; const offs = [];
@ -263,9 +263,9 @@ class PreviewFrame extends React.Component {
const elements = sketchDoc.querySelectorAll(`[${attr}]`); const elements = sketchDoc.querySelectorAll(`[${attr}]`);
const elementsArray = Array.prototype.slice.call(elements); const elementsArray = Array.prototype.slice.call(elements);
elementsArray.forEach((element) => { elementsArray.forEach((element) => {
if (element.getAttribute(attr).match(MEDIA_FILE_REGEX_NO_QUOTES)) { if (element.getAttribute(attr).match(MEDIA_FILE_REGEX)) {
const resolvedFile = resolvePathToFile(element.getAttribute(attr), files); const resolvedFile = resolvePathToFile(element.getAttribute(attr), files);
if (resolvedFile) { if (resolvedFile && resolvedFile.url) {
element.setAttribute(attr, resolvedFile.url); element.setAttribute(attr, resolvedFile.url);
} }
} }
@ -291,7 +291,7 @@ class PreviewFrame extends React.Component {
let jsFileStrings = content.match(STRING_REGEX); let jsFileStrings = content.match(STRING_REGEX);
jsFileStrings = jsFileStrings || []; jsFileStrings = jsFileStrings || [];
jsFileStrings.forEach((jsFileString) => { jsFileStrings.forEach((jsFileString) => {
if (jsFileString.match(MEDIA_FILE_REGEX)) { if (jsFileString.match(MEDIA_FILE_QUOTED_REGEX)) {
const filePath = jsFileString.substr(1, jsFileString.length - 2); const filePath = jsFileString.substr(1, jsFileString.length - 2);
const resolvedFile = resolvePathToFile(filePath, files); const resolvedFile = resolvePathToFile(filePath, files);
if (resolvedFile) { if (resolvedFile) {
@ -315,7 +315,7 @@ class PreviewFrame extends React.Component {
let cssFileStrings = content.match(STRING_REGEX); let cssFileStrings = content.match(STRING_REGEX);
cssFileStrings = cssFileStrings || []; cssFileStrings = cssFileStrings || [];
cssFileStrings.forEach((cssFileString) => { cssFileStrings.forEach((cssFileString) => {
if (cssFileString.match(MEDIA_FILE_REGEX)) { if (cssFileString.match(MEDIA_FILE_QUOTED_REGEX)) {
const filePath = cssFileString.substr(1, cssFileString.length - 2); const filePath = cssFileString.substr(1, cssFileString.length - 2);
const resolvedFile = resolvePathToFile(filePath, files); const resolvedFile = resolvePathToFile(filePath, files);
if (resolvedFile) { if (resolvedFile) {

759
package-lock.json generated

File diff suppressed because it is too large Load diff

24
server/utils/fileUtils.js Normal file
View file

@ -0,0 +1,24 @@
export const fileExtensionsArray = ['gif', 'jpg', 'jpeg', 'png', 'bmp', 'wav', 'flac', 'ogg',
'oga', 'mp4', 'm4p', 'mp3', 'm4a', 'aiff', 'aif', 'm4v', 'aac', 'webm', 'mpg', 'mp2',
'mpeg', 'mpe', 'mpv', 'js', 'jsx', 'html', 'htm', 'css', 'json', 'csv', 'obj', 'svg',
'otf', 'ttf', 'txt', 'mov'];
export const mimeTypes = `image/*,audio/*,text/javascript,text/html,text/css,
application/json,application/x-font-ttf,application/x-font-truetype,text/plain,
text/csv,.obj,video/webm,video/ogg,video/quicktime,video/mp4`;
export const fileExtensions = fileExtensionsArray.map(ext => `.${ext}`).join(',');
export const fileExtensionsAndMimeTypes = `${fileExtensions},${mimeTypes}`;
export const MEDIA_FILE_REGEX =
new RegExp(`^(?!(http:\\/\\/|https:\\/\\/)).*\\.(${fileExtensionsArray.join('|')})$`, 'i');
export const MEDIA_FILE_QUOTED_REGEX =
new RegExp(`^('|")(?!(http:\\/\\/|https:\\/\\/)).*\\.(${fileExtensionsArray.join('|')})('|")$`, 'i');
export const STRING_REGEX = /(['"])((\\\1|.)*?)\1/gm;
export const TEXT_FILE_REGEX = /(.+\.json$|.+\.txt$|.+\.csv$)/i;
export const NOT_EXTERNAL_LINK_REGEX = /^(?!(http:\/\/|https:\/\/))/;
export const EXTERNAL_LINK_REGEX = /^(http:\/\/|https:\/\/)/;

View file

@ -1,9 +1,12 @@
import { resolvePathToFile } from '../utils/filePath'; import { resolvePathToFile } from '../utils/filePath';
// eslint-disable-next-line max-len
const MEDIA_FILE_REGEX_NO_QUOTES = /^(?!(http:\/\/|https:\/\/)).*\.(png|jpg|jpeg|gif|bmp|mp3|wav|aiff|ogg|json|txt|csv|svg|obj|mp4|ogg|webm|mov|otf|ttf|m4a)$/i; import {
const STRING_REGEX = /(['"])((\\\1|.)*?)\1/gm; MEDIA_FILE_REGEX,
const EXTERNAL_LINK_REGEX = /^(http:\/\/|https:\/\/)/; STRING_REGEX,
const NOT_EXTERNAL_LINK_REGEX = /^(?!(http:\/\/|https:\/\/))/; TEXT_FILE_REGEX,
EXTERNAL_LINK_REGEX,
NOT_EXTERNAL_LINK_REGEX
} from './fileUtils';
function resolveLinksInString(content, files, projectId) { function resolveLinksInString(content, files, projectId) {
let newContent = content; let newContent = content;
@ -18,7 +21,7 @@ function resolveLinksInString(content, files, projectId) {
if (resolvedFile) { if (resolvedFile) {
if (resolvedFile.url) { if (resolvedFile.url) {
newContent = newContent.replace(filePath, resolvedFile.url); newContent = newContent.replace(filePath, resolvedFile.url);
} else if (resolvedFile.name.match(/(.+\.json$|.+\.txt$|.+\.csv$)/i)) { } else if (resolvedFile.name.match(TEXT_FILE_REGEX)) {
let resolvedFilePath = filePath; let resolvedFilePath = filePath;
if (resolvedFilePath.startsWith('.')) { if (resolvedFilePath.startsWith('.')) {
resolvedFilePath = resolvedFilePath.substr(1); resolvedFilePath = resolvedFilePath.substr(1);
@ -44,9 +47,9 @@ export function resolvePathsForElementsWithAttribute(attr, sketchDoc, files) {
const elements = sketchDoc.querySelectorAll(`[${attr}]`); const elements = sketchDoc.querySelectorAll(`[${attr}]`);
const elementsArray = Array.prototype.slice.call(elements); const elementsArray = Array.prototype.slice.call(elements);
elementsArray.forEach((element) => { elementsArray.forEach((element) => {
if (element.getAttribute(attr).match(MEDIA_FILE_REGEX_NO_QUOTES)) { if (element.getAttribute(attr).match(MEDIA_FILE_REGEX)) {
const resolvedFile = resolvePathToFile(element.getAttribute(attr), files); const resolvedFile = resolvePathToFile(element.getAttribute(attr), files);
if (resolvedFile) { if (resolvedFile && resolvedFile.url) {
element.setAttribute(attr, resolvedFile.url); element.setAttribute(attr, resolvedFile.url);
} }
} }