diff options
-rw-r--r-- | Makefile | 10 | ||||
-rw-r--r-- | docker/1.4/Dockerfile | 49 | ||||
-rw-r--r-- | docker/1.4/Dockerrun.aws.zip | bin | 0 -> 1043 bytes | |||
-rw-r--r-- | docker/1.4/Dockerrun.aws/.ebextensions/01_files.config | 14 | ||||
-rwxr-xr-x | docker/1.4/Dockerrun.aws/Dockerrun.aws.json | 13 | ||||
-rw-r--r-- | docker/1.4/README.md | 23 | ||||
-rw-r--r-- | docker/1.4/config_docker.json | 111 | ||||
-rwxr-xr-x | docker/1.4/docker-entry.sh | 111 | ||||
-rw-r--r-- | model/version.go | 1 | ||||
-rw-r--r-- | web/react/components/admin_console/email_settings.jsx | 4 | ||||
-rw-r--r-- | web/react/components/file_upload.jsx | 29 | ||||
-rw-r--r-- | web/react/utils/utils.jsx | 15 | ||||
-rw-r--r-- | web/templates/head.html | 2 |
13 files changed, 364 insertions, 18 deletions
@@ -126,10 +126,6 @@ package: cp -RL web/static/js/jquery-dragster $(DIST_PATH)/web/static/js/ cp -RL web/templates $(DIST_PATH)/web - cp -L web/static/js/react-0.14.3.js $(DIST_PATH)/web/static/js/ - cp -L web/static/js/react-dom-0.14.3.js $(DIST_PATH)/web/static/js/ - cp -L web/static/js/react-bootstrap-0.28.1.js $(DIST_PATH)/web/static/js/ - mkdir -p $(DIST_PATH)/api cp -RL api/templates $(DIST_PATH)/api @@ -140,11 +136,11 @@ package: mv $(DIST_PATH)/web/static/js/bundle.min.js $(DIST_PATH)/web/static/js/bundle-$(BUILD_NUMBER).min.js mv $(DIST_PATH)/web/static/js/libs.min.js $(DIST_PATH)/web/static/js/libs-$(BUILD_NUMBER).min.js - #sed -i'.bak' 's|react-0.14.3.js|react-0.14.3.min.js|g' $(DIST_PATH)/web/templates/head.html - #sed -i'.bak' 's|react-dom-0.14.3.js|react-dom-0.14.3.min.js|g' $(DIST_PATH)/web/templates/head.html + sed -i'.bak' 's|react-0.14.3.js|react-0.14.3.min.js|g' $(DIST_PATH)/web/templates/head.html + sed -i'.bak' 's|react-dom-0.14.3.js|react-dom-0.14.3.min.js|g' $(DIST_PATH)/web/templates/head.html sed -i'.bak' 's|jquery-2.1.4.js|jquery-2.1.4.min.js|g' $(DIST_PATH)/web/templates/head.html sed -i'.bak' 's|bootstrap-3.3.5.js|bootstrap-3.3.5.min.js|g' $(DIST_PATH)/web/templates/head.html - #sed -i'.bak' 's|react-bootstrap-0.28.1.js|react-bootstrap-0.28.1.min.js|g' $(DIST_PATH)/web/templates/head.html + sed -i'.bak' 's|react-bootstrap-0.28.1.js|react-bootstrap-0.28.1.min.js|g' $(DIST_PATH)/web/templates/head.html sed -i'.bak' 's|perfect-scrollbar-0.6.7.jquery.js|perfect-scrollbar-0.6.7.jquery.min.js|g' $(DIST_PATH)/web/templates/head.html sed -i'.bak' 's|bundle.js|bundle-$(BUILD_NUMBER).min.js|g' $(DIST_PATH)/web/templates/head.html sed -i'.bak' 's|libs.min.js|libs-$(BUILD_NUMBER).min.js|g' $(DIST_PATH)/web/templates/head.html diff --git a/docker/1.4/Dockerfile b/docker/1.4/Dockerfile new file mode 100644 index 000000000..0e8b8853f --- /dev/null +++ b/docker/1.4/Dockerfile @@ -0,0 +1,49 @@ +# Copyright (c) 2015 Mattermost, Inc. All Rights Reserved. +# See License.txt for license information. +FROM ubuntu:14.04 + +# +# Install SQL +# + +ENV MYSQL_ROOT_PASSWORD=mostest +ENV MYSQL_USER=mmuser +ENV MYSQL_PASSWORD=mostest +ENV MYSQL_DATABASE=mattermost_test + +RUN groupadd -r mysql && useradd -r -g mysql mysql + +RUN apt-key adv --keyserver pool.sks-keyservers.net --recv-keys A4A9406876FCBD3C456770C88C718D3B5072E1F5 + +ENV MYSQL_MAJOR 5.6 +ENV MYSQL_VERSION 5.6.25 + +RUN echo "deb http://repo.mysql.com/apt/debian/ wheezy mysql-${MYSQL_MAJOR}" > /etc/apt/sources.list.d/mysql.list + +RUN apt-get update \ + && export DEBIAN_FRONTEND=noninteractive \ + && apt-get -y install perl wget mysql-server \ + && rm -rf /var/lib/apt/lists/* \ + && rm -rf /var/lib/mysql && mkdir -p /var/lib/mysql + +RUN sed -Ei 's/^(bind-address|log)/#&/' /etc/mysql/my.cnf + +VOLUME /var/lib/mysql +# --------------------------------------------------------------------------------------------------------------------- + +WORKDIR /mattermost + +# Copy over files +RUN wget --no-check-certificate https://s3.amazonaws.com/mattermost-travis-master/mattermost.tar.gz +RUN tar -zxvf mattermost.tar.gz --strip-components=1 && rm mattermost.tar.gz +ADD config_docker.json / +ADD docker-entry.sh / + +RUN chmod +x /docker-entry.sh +ENTRYPOINT /docker-entry.sh + +# Create default storage directory +RUN mkdir /mattermost-data/ + +# Ports +EXPOSE 80 diff --git a/docker/1.4/Dockerrun.aws.zip b/docker/1.4/Dockerrun.aws.zip Binary files differnew file mode 100644 index 000000000..272ea9c54 --- /dev/null +++ b/docker/1.4/Dockerrun.aws.zip diff --git a/docker/1.4/Dockerrun.aws/.ebextensions/01_files.config b/docker/1.4/Dockerrun.aws/.ebextensions/01_files.config new file mode 100644 index 000000000..7f40a8b34 --- /dev/null +++ b/docker/1.4/Dockerrun.aws/.ebextensions/01_files.config @@ -0,0 +1,14 @@ +files: + "/etc/nginx/conf.d/proxy.conf": + mode: "000755" + owner: root + group: root + content: | + client_max_body_size 50M; + "/opt/elasticbeanstalk/hooks/appdeploy/post/init.sh": + mode: "000755" + owner: root + group: root + content: | + #!/usr/bin/env bash + gpasswd -a ec2-user docker diff --git a/docker/1.4/Dockerrun.aws/Dockerrun.aws.json b/docker/1.4/Dockerrun.aws/Dockerrun.aws.json new file mode 100755 index 000000000..654961589 --- /dev/null +++ b/docker/1.4/Dockerrun.aws/Dockerrun.aws.json @@ -0,0 +1,13 @@ +{
+ "AWSEBDockerrunVersion": "1",
+ "Image": {
+ "Name": "mattermost/platform:1.4",
+ "Update": "true"
+ },
+ "Ports": [
+ {
+ "ContainerPort": "80"
+ }
+ ],
+ "Logging": "/var/log/"
+}
diff --git a/docker/1.4/README.md b/docker/1.4/README.md new file mode 100644 index 000000000..f737a1554 --- /dev/null +++ b/docker/1.4/README.md @@ -0,0 +1,23 @@ +Mattermost +========== + +http:/mattermost.org + +Mattermost is an open-source team communication service. It brings team messaging and file sharing into one place, accessible across PCs and phones, with archiving and search. + +Installing Mattermost +===================== + +To run an instance of the latest version of mattermost on your local machine you can run: + +`docker run --name mattermost-dev -d --publish 8065:80 mattermost/platform` + +To update this image to the latest version you can run: + +`docker pull mattermost/platform` + +To run an instance of the latest code from the master branch on GitHub you can run: + +`docker run --name mattermost-dev -d --publish 8065:80 mattermost/platform:dev` + +Any questions, please visit http://forum.mattermost.org diff --git a/docker/1.4/config_docker.json b/docker/1.4/config_docker.json new file mode 100644 index 000000000..1aa2ee843 --- /dev/null +++ b/docker/1.4/config_docker.json @@ -0,0 +1,111 @@ +{ + "ServiceSettings": { + "ListenAddress": ":80", + "MaximumLoginAttempts": 10, + "SegmentDeveloperKey": "", + "GoogleDeveloperKey": "", + "EnableOAuthServiceProvider": false, + "EnableIncomingWebhooks": false, + "EnableOutgoingWebhooks": false, + "EnablePostUsernameOverride": false, + "EnablePostIconOverride": false, + "EnableTesting": false, + "EnableDeveloper": false, + "EnableSecurityFixAlert": true, + "SessionLengthWebInDays" : 30, + "SessionLengthMobileInDays" : 30, + "SessionLengthSSOInDays" : 30, + "SessionCacheInMinutes" : 10 + }, + "TeamSettings": { + "SiteName": "Mattermost", + "MaxUsersPerTeam": 50, + "EnableTeamCreation": true, + "EnableUserCreation": true, + "RestrictCreationToDomains": "", + "RestrictTeamNames": true, + "EnableTeamListing": false + }, + "SqlSettings": { + "DriverName": "mysql", + "DataSource": "mmuser:mostest@tcp(dockerhost:3306)/mattermost_test?charset=utf8mb4,utf8", + "DataSourceReplicas": [], + "MaxIdleConns": 10, + "MaxOpenConns": 10, + "Trace": false, + "AtRestEncryptKey": "7rAh6iwQCkV4cA1Gsg3fgGOXJAQ43QVg" + }, + "LogSettings": { + "EnableConsole": false, + "ConsoleLevel": "INFO", + "EnableFile": true, + "FileLevel": "INFO", + "FileFormat": "", + "FileLocation": "" + }, + "FileSettings": { + "DriverName": "local", + "Directory": "/mattermost/data/", + "EnablePublicLink": true, + "PublicLinkSalt": "A705AklYF8MFDOfcwh3I488G8vtLlVip", + "ThumbnailWidth": 120, + "ThumbnailHeight": 100, + "PreviewWidth": 1024, + "PreviewHeight": 0, + "ProfileWidth": 128, + "ProfileHeight": 128, + "InitialFont": "luximbi.ttf", + "AmazonS3AccessKeyId": "", + "AmazonS3SecretAccessKey": "", + "AmazonS3Bucket": "", + "AmazonS3Region": "", + "AmazonS3Endpoint": "", + "AmazonS3BucketEndpoint": "", + "AmazonS3LocationConstraint": false, + "AmazonS3LowercaseBucket": false + }, + "EmailSettings": { + "EnableSignUpWithEmail": true, + "SendEmailNotifications": false, + "RequireEmailVerification": false, + "FeedbackName": "", + "FeedbackEmail": "", + "SMTPUsername": "", + "SMTPPassword": "", + "SMTPServer": "", + "SMTPPort": "", + "ConnectionSecurity": "", + "InviteSalt": "bjlSR4QqkXFBr7TP4oDzlfZmcNuH9YoS", + "PasswordResetSalt": "vZ4DcKyVVRlKHHJpexcuXzojkE5PZ5eL", + "SendPushNotifications": false, + "PushNotificationServer": "" + }, + "RateLimitSettings": { + "EnableRateLimiter": true, + "PerSec": 10, + "MemoryStoreSize": 10000, + "VaryByRemoteAddr": true, + "VaryByHeader": "" + }, + "PrivacySettings": { + "ShowEmailAddress": true, + "ShowFullName": true + }, + "SupportSettings": { + "TermsOfServiceLink": "/static/help/terms.html", + "PrivacyPolicyLink": "/static/help/privacy.html", + "AboutLink": "/static/help/about.html", + "HelpLink": "/static/help/help.html", + "ReportAProblemLink": "/static/help/report_problem.html", + "SupportEmail": "feedback@mattermost.com" + }, + "GitLabSettings": { + "Enable": false, + "Secret": "", + "Id": "", + "Scope": "", + "AuthEndpoint": "", + "TokenEndpoint": "", + "UserApiEndpoint": "" + } +} diff --git a/docker/1.4/docker-entry.sh b/docker/1.4/docker-entry.sh new file mode 100755 index 000000000..6bd2a1263 --- /dev/null +++ b/docker/1.4/docker-entry.sh @@ -0,0 +1,111 @@ +#!/bin/bash +# Copyright (c) 2015 Mattermost, Inc. All Rights Reserved. +# See License.txt for license information. + +mkdir -p web/static/js + +echo "127.0.0.1 dockerhost" >> /etc/hosts +/etc/init.d/networking restart + +echo configuring mysql + +# SQL!!! +set -e + +get_option () { + local section=$1 + local option=$2 + local default=$3 + ret=$(my_print_defaults $section | grep '^--'${option}'=' | cut -d= -f2-) + [ -z $ret ] && ret=$default + echo $ret +} + + +# Get config +DATADIR="$("mysqld" --verbose --help 2>/dev/null | awk '$1 == "datadir" { print $2; exit }')" +SOCKET=$(get_option mysqld socket "$DATADIR/mysql.sock") +PIDFILE=$(get_option mysqld pid-file "/var/run/mysqld/mysqld.pid") + +if [ ! -d "$DATADIR/mysql" ]; then + if [ -z "$MYSQL_ROOT_PASSWORD" -a -z "$MYSQL_ALLOW_EMPTY_PASSWORD" ]; then + echo >&2 'error: database is uninitialized and MYSQL_ROOT_PASSWORD not set' + echo >&2 ' Did you forget to add -e MYSQL_ROOT_PASSWORD=... ?' + exit 1 + fi + + mkdir -p "$DATADIR" + chown -R mysql:mysql "$DATADIR" + + echo 'Running mysql_install_db' + mysql_install_db --user=mysql --datadir="$DATADIR" --rpm --keep-my-cnf + echo 'Finished mysql_install_db' + + mysqld --user=mysql --datadir="$DATADIR" --skip-networking & + for i in $(seq 30 -1 0); do + [ -S "$SOCKET" ] && break + echo 'MySQL init process in progress...' + sleep 1 + done + if [ $i = 0 ]; then + echo >&2 'MySQL init process failed.' + exit 1 + fi + + # These statements _must_ be on individual lines, and _must_ end with + # semicolons (no line breaks or comments are permitted). + # TODO proper SQL escaping on ALL the things D: + + tempSqlFile=$(mktemp /tmp/mysql-first-time.XXXXXX.sql) + cat > "$tempSqlFile" <<-EOSQL + -- What's done in this file shouldn't be replicated + -- or products like mysql-fabric won't work + SET @@SESSION.SQL_LOG_BIN=0; + + DELETE FROM mysql.user ; + CREATE USER 'root'@'%' IDENTIFIED BY '${MYSQL_ROOT_PASSWORD}' ; + GRANT ALL ON *.* TO 'root'@'%' WITH GRANT OPTION ; + DROP DATABASE IF EXISTS test ; + EOSQL + + if [ "$MYSQL_DATABASE" ]; then + echo "CREATE DATABASE IF NOT EXISTS \`$MYSQL_DATABASE\` ;" >> "$tempSqlFile" + fi + + if [ "$MYSQL_USER" -a "$MYSQL_PASSWORD" ]; then + echo "CREATE USER '"$MYSQL_USER"'@'%' IDENTIFIED BY '"$MYSQL_PASSWORD"' ;" >> "$tempSqlFile" + + if [ "$MYSQL_DATABASE" ]; then + echo "GRANT ALL ON \`"$MYSQL_DATABASE"\`.* TO '"$MYSQL_USER"'@'%' ;" >> "$tempSqlFile" + fi + fi + + echo 'FLUSH PRIVILEGES ;' >> "$tempSqlFile" + + mysql -uroot < "$tempSqlFile" + + rm -f "$tempSqlFile" + kill $(cat $PIDFILE) + for i in $(seq 30 -1 0); do + [ -f "$PIDFILE" ] || break + echo 'MySQL init process in progress...' + sleep 1 + done + if [ $i = 0 ]; then + echo >&2 'MySQL hangs during init process.' + exit 1 + fi + echo 'MySQL init process done. Ready for start up.' +fi + +chown -R mysql:mysql "$DATADIR" + +mysqld & + +sleep 5 + +# ------------------------ + +echo starting platform +cd /mattermost/bin +./platform -config=/config_docker.json diff --git a/model/version.go b/model/version.go index 142ddb371..88334ceea 100644 --- a/model/version.go +++ b/model/version.go @@ -12,6 +12,7 @@ import ( // It should be maitained in chronological order with most current // release at the front of the list. var versions = []string{ + "1.4.0", "1.3.0", "1.2.1", "1.2.0", diff --git a/web/react/components/admin_console/email_settings.jsx b/web/react/components/admin_console/email_settings.jsx index 91d73dccd..193fd4147 100644 --- a/web/react/components/admin_console/email_settings.jsx +++ b/web/react/components/admin_console/email_settings.jsx @@ -581,12 +581,12 @@ export default class EmailSettings extends React.Component { className='form-control' id='PushNotificationServer' ref='PushNotificationServer' - placeholder='E.g.: "https://push.mattermost.com"' + placeholder='E.g.: "https://push-test.mattermost.com"' defaultValue={this.props.config.EmailSettings.PushNotificationServer} onChange={this.handleChange} disabled={!this.state.sendPushNotifications} /> - <p className='help-text'>{'Location of Mattermost push notification service you can set up behind your firewall using https://github.com/mattermost/push-proxy. For testing you can use https://push.mattermost.com, which connects to the sample Mattermost iOS app in the public Apple AppStore. Please do not use test service for production deployments.'}</p> + <p className='help-text'>{'Location of Mattermost push notification service you can set up behind your firewall using https://github.com/mattermost/push-proxy. For testing you can use https://push-test.mattermost.com, which connects to the sample Mattermost iOS app in the public Apple AppStore. Please do not use test service for production deployments.'}</p> </div> </div> diff --git a/web/react/components/file_upload.jsx b/web/react/components/file_upload.jsx index a0c930ffb..6337afabc 100644 --- a/web/react/components/file_upload.jsx +++ b/web/react/components/file_upload.jsx @@ -4,7 +4,7 @@ import * as client from '../utils/client.jsx'; import Constants from '../utils/constants.jsx'; import ChannelStore from '../stores/channel_store.jsx'; -import * as utils from '../utils/utils.jsx'; +import * as Utils from '../utils/utils.jsx'; export default class FileUpload extends React.Component { constructor(props) { @@ -52,7 +52,7 @@ export default class FileUpload extends React.Component { } // generate a unique id that can be used by other components to refer back to this upload - let clientId = utils.generateId(); + let clientId = Utils.generateId(); // prepare data to be uploaded var formData = new FormData(); @@ -121,14 +121,14 @@ export default class FileUpload extends React.Component { enter(dragsterEvent, e) { var files = e.originalEvent.dataTransfer; - if (utils.isFileTransfer(files)) { + if (Utils.isFileTransfer(files)) { $('.center-file-overlay').removeClass('hidden'); } }, leave(dragsterEvent, e) { var files = e.originalEvent.dataTransfer; - if (utils.isFileTransfer(files)) { + if (Utils.isFileTransfer(files)) { $('.center-file-overlay').addClass('hidden'); } }, @@ -142,14 +142,14 @@ export default class FileUpload extends React.Component { enter(dragsterEvent, e) { var files = e.originalEvent.dataTransfer; - if (utils.isFileTransfer(files)) { + if (Utils.isFileTransfer(files)) { $('.right-file-overlay').removeClass('hidden'); } }, leave(dragsterEvent, e) { var files = e.originalEvent.dataTransfer; - if (utils.isFileTransfer(files)) { + if (Utils.isFileTransfer(files)) { $('.right-file-overlay').addClass('hidden'); } }, @@ -205,7 +205,7 @@ export default class FileUpload extends React.Component { var channelId = self.props.channelId || ChannelStore.getCurrentId(); // generate a unique id that can be used by other components to refer back to this file upload - var clientId = utils.generateId(); + var clientId = Utils.generateId(); var formData = new FormData(); formData.append('channel_id', channelId); @@ -268,6 +268,18 @@ export default class FileUpload extends React.Component { } render() { + let multiple = true; + if (Utils.isMobileApp()) { + // iOS WebViews don't upload videos properly in multiple mode + multiple = false; + } + + let accept = ''; + if (Utils.isIosChrome()) { + // iOS Chrome can't upload videos at all + accept = 'image/*'; + } + return ( <span ref='input' @@ -280,7 +292,8 @@ export default class FileUpload extends React.Component { ref='fileInput' type='file' onChange={this.handleChange} - multiple='true' + multiple={multiple} + accept={accept} /> </span> ); diff --git a/web/react/utils/utils.jsx b/web/react/utils/utils.jsx index 95eca7c3a..2ddd0e5e3 100644 --- a/web/react/utils/utils.jsx +++ b/web/react/utils/utils.jsx @@ -74,6 +74,21 @@ export function isSafari() { return false; } +export function isIosChrome() { + // https://developer.chrome.com/multidevice/user-agent + return navigator.userAgent.indexOf('CriOS') !== -1; +} + +export function isMobileApp() { + const userAgent = navigator.userAgent; + + // the mobile app has different user agents for the native api calls and the shim, so handle them both + const isApi = userAgent.indexOf('Mattermost') !== -1; + const isShim = userAgent.indexOf('iPhone') !== -1 && userAgent.indexOf('Safari') === -1 && userAgent.indexOf('Chrome') === -1; + + return isApi || isShim; +} + export function isInRole(roles, inRole) { var parts = roles.split(' '); for (var i = 0; i < parts.length; i++) { diff --git a/web/templates/head.html b/web/templates/head.html index 70c94e8ff..08d8726ea 100644 --- a/web/templates/head.html +++ b/web/templates/head.html @@ -98,7 +98,7 @@ }); if (window.mm_config.EnableDeveloper === 'true') { - window.ErrorStore.storeLastError('DEVELOPER MODE: A javascript error has occured. Please use the javascript console to capture and report the error (row: ' + line + ' col: ' + column + ').'); + window.ErrorStore.storeLastError({message: 'DEVELOPER MODE: A javascript error has occured. Please use the javascript console to capture and report the error (row: ' + line + ' col: ' + column + ').'}); window.ErrorStore.emitChange(); } } |