summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorasaadmahmoodspin <asaad@battlehouse.com>2015-06-19 19:52:04 +0500
committerasaadmahmoodspin <asaad@battlehouse.com>2015-06-19 19:52:04 +0500
commit20676fd740781e3b818b7411be17ec6f4f67bc3f (patch)
tree059988228781471d43fd212525cb3bd53de0e040
parent0821b51f4ee5fcc2eadc2c92c60ebbb4fdc084d3 (diff)
parent32025e43799324523988af040085d95ec6b6e80e (diff)
downloadchat-20676fd740781e3b818b7411be17ec6f4f67bc3f.tar.gz
chat-20676fd740781e3b818b7411be17ec6f4f67bc3f.tar.bz2
chat-20676fd740781e3b818b7411be17ec6f4f67bc3f.zip
Merge pull request #1 from rgarmsen2295/mm-1253
MM-1253
-rw-r--r--Dockerfile99
-rw-r--r--NOTICE.txt11
-rw-r--r--README.md33
-rw-r--r--config/config.json3
-rw-r--r--config/config_docker.json85
-rwxr-xr-xdocker/docker-entry.sh122
-rw-r--r--docker/main.cf28
-rw-r--r--store/sql_team_store_test.go5
-rw-r--r--utils/config.go11
-rw-r--r--utils/config_test.go15
-rw-r--r--utils/mail.go93
-rw-r--r--web/react/components/login.jsx10
-rw-r--r--web/react/components/post_list.jsx14
-rw-r--r--web/react/components/signup_team_complete.jsx3
-rw-r--r--web/react/components/signup_user_complete.jsx1
-rw-r--r--web/react/components/textbox.jsx2
-rw-r--r--web/react/utils/utils.jsx12
-rw-r--r--web/static/config/config.js4
18 files changed, 489 insertions, 62 deletions
diff --git a/Dockerfile b/Dockerfile
new file mode 100644
index 000000000..5c389c056
--- /dev/null
+++ b/Dockerfile
@@ -0,0 +1,99 @@
+# Copyright (c) 2015 Spinpunch, Inc. All Rights Reserved.
+# See License.txt for license information.
+FROM ubuntu:14.04
+
+# Install Dependancies
+RUN apt-get update && apt-get install -y build-essential
+RUN apt-get install -y curl
+RUN curl -sL https://deb.nodesource.com/setup | bash -
+RUN apt-get install -y nodejs
+RUN apt-get install -y ruby-full
+RUN gem install compass
+
+# Postfix
+RUN apt-get install -y postfix
+
+#
+# Install GO
+#
+
+RUN apt-get update && apt-get install -y \
+ gcc libc6-dev make git mercurial \
+ --no-install-recommends \
+ && rm -rf /var/lib/apt/lists/*
+
+ENV GOLANG_VERSION 1.4.2
+
+RUN curl -sSL https://golang.org/dl/go$GOLANG_VERSION.src.tar.gz \
+ | tar -v -C /usr/src -xz
+
+RUN cd /usr/src/go/src && ./make.bash --no-clean 2>&1
+
+ENV PATH /usr/src/go/bin:$PATH
+
+RUN mkdir -p /go/src /go/bin && chmod -R 777 /go
+ENV GOPATH /go
+ENV PATH /go/bin:$PATH
+WORKDIR /go
+
+# ---------------------------------------------------------------------------------------------------------------------
+
+#
+# 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-get update && apt-get install -y perl --no-install-recommends && rm -rf /var/lib/apt/lists/*
+
+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 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
+# ---------------------------------------------------------------------------------------------------------------------
+
+#
+# Install Redis
+#
+
+RUN apt-get update && apt-get install -y wget
+RUN wget http://download.redis.io/redis-stable.tar.gz; \
+ tar xvzf redis-stable.tar.gz; \
+ cd redis-stable; \
+ make install
+
+# ---------------------------------------------------------------------------------------------------------------------
+
+# Copy over files
+ADD . /go/src/github.com/mattermost/platform
+
+# Insert postfix config
+ADD ./docker/main.cf /etc/postfix/
+
+RUN go get github.com/tools/godep
+RUN cd /go/src/github.com/mattermost/platform; godep restore
+RUN go install github.com/mattermost/platform
+RUN cd /go/src/github.com/mattermost/platform/web/react; npm install
+
+RUN chmod +x /go/src/github.com/mattermost/platform/docker/docker-entry.sh
+ENTRYPOINT /go/src/github.com/mattermost/platform/docker/docker-entry.sh
+
+# Ports
+EXPOSE 80
diff --git a/NOTICE.txt b/NOTICE.txt
index 07c6a8bf4..fd5fc74b5 100644
--- a/NOTICE.txt
+++ b/NOTICE.txt
@@ -1,4 +1,11 @@
Mattermost Platform Preview
-Copyright 2015 SpinPunch, Inc.
+© 2015 Spinpunch, Inc. All Rights Reserved. See LICENSE.txt for license information.
-Regular expression support is provided by the PCRE library package, which is open source software, written by Philip Hazel, and copyright by the University of Cambridge, England. The original software is available from ftp://ftp.csx.cam.ac.uk/pub/software/programming/pcre/
+NOTICES:
+
+This product contains a modified portion of 'draw2d', a Go library to draw 2d geometrical forms on images by Laurent Le Goff
+
+* LICENSE:
+ * http://opensource.org/licenses/BSD-3-Clause (BSD 3-Clause)
+* HOMEPAGE:
+ * https://code.google.com/p/draw2d/
diff --git a/README.md b/README.md
index 0676b8903..c3e844f61 100644
--- a/README.md
+++ b/README.md
@@ -1,4 +1,4 @@
-**Mattermost (Preview)<br>**
+**Mattermost Preview<br>**
**Team Communication Service<br>**
**Version 0.40**
@@ -21,23 +21,24 @@ That said, any issues at all, please let us know on the Mattermost forum at: htt
Developer Machine Setup (Mac)
-----------------------------
-DOCKER
+DOCKER SETUP
-1. Follow the instructions at http://docs.docker.com/installation/mac/ Use the Boot2Docker command-line utility
-If you do command-line setup use: `boot2docker init eval “$(boot2docker shellinit)”`
+1. Follow the instructions at http://docs.docker.com/installation/mac/
+<br>a) Use the Boot2Docker command-line utility
+<br>b) If you do command-line setup use: `boot2docker init eval “$(boot2docker shellinit)”`
2. Get your Docker IP address with `boot2docker ip`
3. Add a line to your /etc/hosts that goes `<Docker IP> dockerhost`
4. Run `boot2docker shellinit` and copy the export statements to your ~/.bash_profile
Any issues? Please let us know on our forums at: http://bit.ly/1MY1kul
-GO
+GO SETUP
1. Download Go from http://golang.org/dl/
NODE.JS SETUP
-1. Install homebrew from brew.sh
+1. Install homebrew from http://brew.sh
2. `brew install node`
COMPASS SETUP
@@ -47,23 +48,19 @@ COMPASS SETUP
MATTERMOST SETUP
-1. Make a project directory for Mattermost, which will for the rest of this document be referred to as $PROJECT
-2. Make a go directory in your $PROJECT directory
-3. Create/Open your ~/.bash_profile and add the following lines: `export GOPATH=$PROJECT/go export PATH=$PATH:$GOPATH/bin`
-4. Refresh your bash profile with `source ~/.bash_profile`
-5. `cd $GOPATH`
-6. `mkdir -p src/github.com/mattermost` then cd into this directory
-7. `git clone github.com/mattermost/platform.git`
-8. If you do not have Mercurial, download it with: `brew install mercurial`
-9. `cd platform`
-10. `make test`
-11. Provided the test runs fine, you now have a complete build environment. Use `make run` to run your code
+1. Make a project directory for Mattermost, which we'll call **$PROJECT** for the rest of these instructions
+2. Make a `go` directory in your $PROJECT directory
+3. Open or create your ~/.bash_profile and add the following lines: <br> `export GOPATH=$PROJECT/go`<br> `export PATH=$PATH:$GOPATH/bin` <br>then refresh your bash profile with `source ~/.bash_profile`
+4. Then use `cd $GOPATH` and `mkdir -p src/github.com/mattermost` then cd into this directory and run `git clone github.com/mattermost/platform.git`
+5. If you do not have Mercurial, download it with: `brew install mercurial`
+6. Then do `cd platform` and `make test`. Provided the test runs fine, you now have a complete build environment.
+7. Use `make run` to run your code
Any issues? Please let us know on our forums at: http://bit.ly/1MY1kul
License
-------
-Mattermost Preview uses the Apache 2.0 open source license. For more details see: http://bit.ly/1Lc25Sv<br>
+This software uses the Apache 2.0 open source license. For more details see: http://bit.ly/1Lc25Sv<br>
**XXXXXX TODO: Test install procedures**
diff --git a/config/config.json b/config/config.json
index a6c79efac..1b844c259 100644
--- a/config/config.json
+++ b/config/config.json
@@ -8,7 +8,7 @@
"FileLocation": ""
},
"ServiceSettings": {
- "SiteName": "XXXXXXMustBeFilledIn",
+ "SiteName": "Mattermost Preview",
"Domain": "xxxxxxmustbefilledin.com",
"Mode" : "dev",
"AllowTesting" : false,
@@ -57,6 +57,7 @@
"SMTPUsername": "",
"SMTPPassword": "",
"SMTPServer": "",
+ "UseTLS": false,
"FeedbackEmail": "feedback@xxxxxxmustbefilledin.com",
"FeedbackName": "",
"ApplePushServer": "",
diff --git a/config/config_docker.json b/config/config_docker.json
new file mode 100644
index 000000000..f2e56bef8
--- /dev/null
+++ b/config/config_docker.json
@@ -0,0 +1,85 @@
+{
+ "LogSettings": {
+ "ConsoleEnable": false,
+ "ConsoleLevel": "DEBUG",
+ "FileEnable": true,
+ "FileLevel": "INFO",
+ "FileFormat": "",
+ "FileLocation": ""
+ },
+ "ServiceSettings": {
+ "SiteName": "Mattermost Preview",
+ "Domain": "",
+ "Mode" : "prod",
+ "AllowTesting" : false,
+ "UseSSL": false,
+ "Port": "80",
+ "Version": "developer",
+ "Shards": {
+ },
+ "InviteSalt": "gxHVDcKUyP2y1eiyW8S8na1UYQAfq6J6",
+ "PublicLinkSalt": "TO3pTyXIZzwHiwyZgGql7lM7DG3zeId4",
+ "ResetSalt": "IPxFzSfnDFsNsRafZxz8NaYqFKhf9y2t",
+ "AnalyticsUrl": ""
+ },
+ "SqlSettings": {
+ "DriverName": "mysql",
+ "DataSource": "mmuser:mostest@tcp(localhost:3306)/mattermost_test",
+ "DataSourceReplicas": ["mmuser:mostest@tcp(localhost:3306)/mattermost_test"],
+ "MaxIdleConns": 10,
+ "MaxOpenConns": 10,
+ "Trace": false,
+ "AtRestEncryptKey": "Ya0xMrybACJ3sZZVWQC7e31h5nSDWZFS"
+ },
+ "RedisSettings": {
+ "DataSource": "localhost:6379",
+ "MaxOpenConns": 1000
+ },
+ "AWSSettings": {
+ "S3AccessKeyId": "",
+ "S3SecretAccessKey": "",
+ "S3Bucket": "",
+ "S3Region": "",
+ "Route53AccessKeyId": "",
+ "Route53SecretAccessKey": "",
+ "Route53ZoneId": "",
+ "Route53Region": ""
+ },
+ "ImageSettings": {
+ "ThumbnailWidth": 200,
+ "ThumbnailHeight": 0,
+ "PreviewWidth": 1024,
+ "PreviewHeight": 0,
+ "ProfileWidth": 128,
+ "ProfileHeight": 128
+ },
+ "EmailSettings": {
+ "SMTPUsername": "",
+ "SMTPPassword": "",
+ "SMTPServer": "localhost:25",
+ "UseTLS": false,
+ "FeedbackEmail": "feedback@xxxxxxmustbefilledin.com",
+ "FeedbackName": "",
+ "ApplePushServer": "",
+ "ApplePushCertPublic": "",
+ "ApplePushCertPrivate": ""
+ },
+ "PrivacySettings": {
+ "ShowEmailAddress": true,
+ "ShowPhoneNumber": true,
+ "ShowSkypeId": true,
+ "ShowFullName": true
+ },
+ "TeamSettings": {
+ "MaxUsersPerTeam": 150,
+ "AllowPublicLink": true,
+ "AllowValet": false,
+ "TermsLink": "/static/help/configure_links.html",
+ "PrivacyLink": "/static/help/configure_links.html",
+ "AboutLink": "/static/help/configure_links.html",
+ "HelpLink": "/static/help/configure_links.html",
+ "ReportProblemLink": "/static/help/configure_links.html",
+ "TourLink": "/static/help/configure_links.html",
+ "DefaultThemeColor": "#2389D7"
+ }
+}
diff --git a/docker/docker-entry.sh b/docker/docker-entry.sh
new file mode 100755
index 000000000..cfa589041
--- /dev/null
+++ b/docker/docker-entry.sh
@@ -0,0 +1,122 @@
+#!/bin/bash
+# Copyright (c) 2015 Spinpunch, 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 postfix
+/etc/init.d/postfix restart
+
+echo starting redis
+redis-server &
+
+echo starting react processor
+cd /go/src/github.com/mattermost/platform/web/react && npm start &
+
+echo starting go web server
+cd /go/src/github.com/mattermost/platform/; go run mattermost.go -config=config_docker.json &
+
+echo starting compass watch
+cd /go/src/github.com/mattermost/platform/web/sass-files && compass watch
diff --git a/docker/main.cf b/docker/main.cf
new file mode 100644
index 000000000..ed97d37ef
--- /dev/null
+++ b/docker/main.cf
@@ -0,0 +1,28 @@
+myorigin = mattermost.com
+myhostname = mattermost.com
+
+smtpd_banner = $myhostname ESMTP $mail_name (Ubuntu)
+biff = no
+
+append_dot_mydomain = no
+
+readme_directory = no
+
+# TLS parameters
+smtpd_tls_cert_file=/etc/ssl/certs/ssl-cert-snakeoil.pem
+smtpd_tls_key_file=/etc/ssl/private/ssl-cert-snakeoil.key
+smtpd_use_tls=no
+smtp_use_tls=no
+smtpd_tls_session_cache_database = btree:${data_directory}/smtpd_scache
+smtp_tls_session_cache_database = btree:${data_directory}/smtp_scache
+
+smtpd_relay_restrictions = permit_mynetworks permit_sasl_authenticated defer_unauth_destination
+alias_maps = hash:/etc/aliases
+alias_database = hash:/etc/aliases
+mydestination = localhost, localhost.localdomain, localhost
+relayhost =
+mynetworks = 127.0.0.0/8 [::ffff:127.0.0.0]/104 [::1]/128
+mailbox_size_limit = 0
+recipient_delimiter = +
+inet_interfaces = all
+inet_protocols = all
diff --git a/store/sql_team_store_test.go b/store/sql_team_store_test.go
index 981817d90..1b03b75fd 100644
--- a/store/sql_team_store_test.go
+++ b/store/sql_team_store_test.go
@@ -109,7 +109,10 @@ func TestTeamStoreGetByDomain(t *testing.T) {
o1.Domain = "a" + model.NewId() + "b"
o1.Email = model.NewId() + "@nowhere.com"
o1.Type = model.TEAM_OPEN
- <-store.Team().Save(&o1)
+
+ if err := (<-store.Team().Save(&o1)).Err; err != nil {
+ t.Fatal(err)
+ }
if r1 := <-store.Team().GetByDomain(o1.Domain); r1.Err != nil {
t.Fatal(r1.Err)
diff --git a/utils/config.go b/utils/config.go
index 1060c7550..418041706 100644
--- a/utils/config.go
+++ b/utils/config.go
@@ -79,6 +79,7 @@ type EmailSettings struct {
SMTPUsername string
SMTPPassword string
SMTPServer string
+ UseTLS bool
FeedbackEmail string
FeedbackName string
ApplePushServer string
@@ -216,6 +217,16 @@ func LoadConfig(fileName string) {
panic("Error decoding configuration " + err.Error())
}
+ // Grabs the domain from enviroment variable if not in configuration
+ if config.ServiceSettings.Domain == "" {
+ config.ServiceSettings.Domain = os.Getenv("MATTERMOST_DOMAIN")
+ }
+
+ // Validates our mail settings
+ if err := CheckMailSettings(); err != nil {
+ l4g.Error("Email settings are not valid err=%v", err)
+ }
+
configureLog(config.LogSettings)
Cfg = &config
diff --git a/utils/config_test.go b/utils/config_test.go
index 4d37b4e88..9067dc647 100644
--- a/utils/config_test.go
+++ b/utils/config_test.go
@@ -4,9 +4,24 @@
package utils
import (
+ "os"
"testing"
)
func TestConfig(t *testing.T) {
LoadConfig("config.json")
}
+
+func TestEnvOverride(t *testing.T) {
+ os.Setenv("MATTERMOST_DOMAIN", "testdomain.com")
+
+ LoadConfig("config_docker.json")
+ if Cfg.ServiceSettings.Domain != "testdomain.com" {
+ t.Fail()
+ }
+
+ LoadConfig("config.json")
+ if Cfg.ServiceSettings.Domain == "testdomain.com" {
+ t.Fail()
+ }
+}
diff --git a/utils/mail.go b/utils/mail.go
index b8c2f4f9b..2fb7f801d 100644
--- a/utils/mail.go
+++ b/utils/mail.go
@@ -13,6 +13,69 @@ import (
"net/smtp"
)
+func CheckMailSettings() *model.AppError {
+ if len(Cfg.EmailSettings.SMTPServer) == 0 {
+ return model.NewAppError("CheckMailSettings", "No email settings present, mail will not be sent", "")
+ }
+ conn, err := connectToSMTPServer()
+ if err != nil {
+ return err
+ }
+ defer conn.Close()
+ c, err2 := newSMTPClient(conn)
+ if err2 != nil {
+ return err
+ }
+ defer c.Quit()
+ defer c.Close()
+
+ return nil
+}
+
+func connectToSMTPServer() (net.Conn, *model.AppError) {
+ host, _, _ := net.SplitHostPort(Cfg.EmailSettings.SMTPServer)
+
+ var conn net.Conn
+ var err error
+
+ if Cfg.EmailSettings.UseTLS {
+ tlsconfig := &tls.Config{
+ InsecureSkipVerify: true,
+ ServerName: host,
+ }
+
+ conn, err = tls.Dial("tcp", Cfg.EmailSettings.SMTPServer, tlsconfig)
+ if err != nil {
+ return nil, model.NewAppError("SendMail", "Failed to open TLS connection", err.Error())
+ }
+ } else {
+ conn, err = net.Dial("tcp", Cfg.EmailSettings.SMTPServer)
+ if err != nil {
+ return nil, model.NewAppError("SendMail", "Failed to open connection", err.Error())
+ }
+ }
+
+ return conn, nil
+}
+
+func newSMTPClient(conn net.Conn) (*smtp.Client, *model.AppError) {
+ host, _, _ := net.SplitHostPort(Cfg.EmailSettings.SMTPServer)
+ c, err := smtp.NewClient(conn, host)
+ if err != nil {
+ l4g.Error("Failed to open a connection to SMTP server %v", err)
+ return nil, model.NewAppError("SendMail", "Failed to open TLS connection", err.Error())
+ }
+ // GO does not support plain auth over a non encrypted connection.
+ // so if not tls then no auth
+ auth := smtp.PlainAuth("", Cfg.EmailSettings.SMTPUsername, Cfg.EmailSettings.SMTPPassword, host)
+ if Cfg.EmailSettings.UseTLS {
+ if err = c.Auth(auth); err != nil {
+ return nil, model.NewAppError("SendMail", "Failed to authenticate on SMTP server", err.Error())
+ }
+ }
+ return c, nil
+}
+
func SendMail(to, subject, body string) *model.AppError {
fromMail := mail.Address{"", Cfg.EmailSettings.FeedbackEmail}
@@ -36,38 +99,24 @@ func SendMail(to, subject, body string) *model.AppError {
return nil
}
- host, _, _ := net.SplitHostPort(Cfg.EmailSettings.SMTPServer)
-
- auth := smtp.PlainAuth("", Cfg.EmailSettings.SMTPUsername, Cfg.EmailSettings.SMTPPassword, host)
-
- tlsconfig := &tls.Config{
- InsecureSkipVerify: true,
- ServerName: host,
- }
-
- conn, err := tls.Dial("tcp", Cfg.EmailSettings.SMTPServer, tlsconfig)
- if err != nil {
- return model.NewAppError("SendMail", "Failed to open TLS connection", err.Error())
+ conn, err1 := connectToSMTPServer()
+ if err1 != nil {
+ return err1
}
defer conn.Close()
- c, err := smtp.NewClient(conn, host)
- if err != nil {
- l4g.Error("Failed to open a connection to SMTP server %v", err)
- return model.NewAppError("SendMail", "Failed to open TLS connection", err.Error())
+ c, err2 := newSMTPClient(conn)
+ if err2 != nil {
+ return err2
}
defer c.Quit()
defer c.Close()
- if err = c.Auth(auth); err != nil {
- return model.NewAppError("SendMail", "Failed to authenticate on SMTP server", err.Error())
- }
-
- if err = c.Mail(fromMail.Address); err != nil {
+ if err := c.Mail(fromMail.Address); err != nil {
return model.NewAppError("SendMail", "Failed to add from email address", err.Error())
}
- if err = c.Rcpt(toMail.Address); err != nil {
+ if err := c.Rcpt(toMail.Address); err != nil {
return model.NewAppError("SendMail", "Failed to add to email address", err.Error())
}
diff --git a/web/react/components/login.jsx b/web/react/components/login.jsx
index 8d82a4b62..65f1da1f8 100644
--- a/web/react/components/login.jsx
+++ b/web/react/components/login.jsx
@@ -52,20 +52,20 @@ var FindTeamDomain = React.createClass({
<div>
<span className="signup-team__name">{ config.SiteName }</span>
<br/>
- <span className="signup-team__subdomain">Enter your {strings.TeamPlural} domain.</span>
+ <span className="signup-team__subdomain">Enter your {strings.Team}'s domain.</span>
<br/>
<br/>
</div>
<form onSubmit={this.handleSubmit}>
<div className={server_error ? 'form-group has-error' : 'form-group'}>
{ server_error }
- <input type="text" className="form-control" name="domain" ref="domain" placeholder="teamdomain" />
+ <input type="text" className="form-control" name="domain" ref="domain" placeholder="team domain" />
</div>
<div className="form-group">
<button type="submit" className="btn btn-primary">Continue</button>
</div>
<div>
- <span>Don't remember your {strings.TeamPlural} domain? <a href="/find_team">Find it here</a></span>
+ <span>Don't remember your {strings.Team}'s domain? <a href="/find_team">Find it here</a></span>
</div>
<br/>
<br/>
@@ -74,7 +74,7 @@ var FindTeamDomain = React.createClass({
<br/>
<br/>
<div>
- <span>{"Want to create your own " + strings.Team + "?"} <a href="/" className="signup-team-login">Sign up now</a></span>
+ <span>{"Want to create your own " + strings.Team + "?"} <a href={utils.getHomeLink()} className="signup-team-login">Sign up now</a></span>
</div>
</form>
</div>
@@ -188,7 +188,7 @@ module.exports = React.createClass({
<a href="/reset_password">I forgot my password</a>
</div>
<div className="external-link">
- <span>{"Want to create your own " + strings.Team + "?"} <a href={config.HomeLink} className="signup-team-login">Sign up now</a></span>
+ <span>{"Want to create your own " + strings.Team + "?"} <a href={utils.getHomeLink()} className="signup-team-login">Sign up now</a></span>
</div>
</form>
</div>
diff --git a/web/react/components/post_list.jsx b/web/react/components/post_list.jsx
index 65247b705..97f9fa943 100644
--- a/web/react/components/post_list.jsx
+++ b/web/react/components/post_list.jsx
@@ -444,17 +444,13 @@ module.exports = React.createClass({
if (post.create_at > last_viewed && !rendered_last_viewed) {
rendered_last_viewed = true;
postCtls.push(
- <div>
- <div className="new-seperator">
- <hr id="new_message" className="new-seperator__hr" />
- <div className="new-seperator__text">New Messages</div>
- </div>
- {postCtl}
- </div>
+ <div className="new-seperator">
+ <hr id="new_message" className="new-seperator__hr" />
+ <div className="new-seperator__text">New Messages</div>
+ </div>
);
- } else {
- postCtls.push(postCtl);
}
+ postCtls.push(postCtl);
previousPostDay = utils.getDateForUnixTicks(post.create_at);
}
diff --git a/web/react/components/signup_team_complete.jsx b/web/react/components/signup_team_complete.jsx
index 066161a10..b038679e6 100644
--- a/web/react/components/signup_team_complete.jsx
+++ b/web/react/components/signup_team_complete.jsx
@@ -467,7 +467,8 @@ UsernamePage = React.createClass({
</div>
{ name_error }
</div>
- <p>{"Pick something " + strings.Team + "mates will recognize. Your username is how you will appear to others"}</p>
+ <p>{"Pick something " + strings.Team + "mates will recognize. Your username is how you will appear to others."}</p>
+ <p>It can be made of lowercase letters and numbers.</p>
<button className="btn btn-default" onClick={this.submitBack}><i className="glyphicon glyphicon-chevron-left"></i> Back</button>&nbsp;
<button className="btn-primary btn" onClick={this.submitNext}>Next<i className="glyphicon glyphicon-chevron-right"></i></button>
</div>
diff --git a/web/react/components/signup_user_complete.jsx b/web/react/components/signup_user_complete.jsx
index 0fcdc92b0..146419cf5 100644
--- a/web/react/components/signup_user_complete.jsx
+++ b/web/react/components/signup_user_complete.jsx
@@ -120,6 +120,7 @@ module.exports = React.createClass({
<img className="signup-team-logo" src="/static/images/logo.png" />
<h4>Welcome to { config.SiteName }</h4>
<p>{"Choose your username and password for the " + this.props.team_name + " " + strings.Team +"."}</p>
+ <p>Your username can be made of lowercase letters and numbers.</p>
<label className="control-label">Username</label>
<div className={ name_error ? "form-group has-error" : "form-group" }>
<input type="text" ref="name" className="form-control" placeholder="" maxLength="128" />
diff --git a/web/react/components/textbox.jsx b/web/react/components/textbox.jsx
index 45798809f..7a4762e07 100644
--- a/web/react/components/textbox.jsx
+++ b/web/react/components/textbox.jsx
@@ -204,7 +204,7 @@ module.exports = React.createClass({
// If there is a space after the last @, nothing to do.
if (lastSpace > atIndex || lastCharSpace > atIndex) {
- this.setState({ mentionText: '-1' });
+ this.updateMentionTab('-1', null);
return;
}
diff --git a/web/react/utils/utils.jsx b/web/react/utils/utils.jsx
index 72ed48faf..628d92342 100644
--- a/web/react/utils/utils.jsx
+++ b/web/react/utils/utils.jsx
@@ -730,3 +730,15 @@ Image.prototype.load = function(url, progressCallback) {
};
Image.prototype.completedPercentage = 0;
+
+module.exports.getHomeLink = function() {
+ if (config.HomeLink != "") {
+ return config.HomeLink;
+ }
+ var parts = window.location.host.split(".");
+ if (parts.length <= 1) {
+ return window.location.protocol + "//" + window.location.host;
+ }
+ parts[0] = "www";
+ return window.location.protocol + "//" + parts.join(".");
+}
diff --git a/web/static/config/config.js b/web/static/config/config.js
index 080f16a30..82d4bbf70 100644
--- a/web/static/config/config.js
+++ b/web/static/config/config.js
@@ -24,7 +24,7 @@ var config = {
AboutLink: "/static/help/configure_links.html",
HelpLink: "/static/help/configure_links.html",
ReportProblemLink: "/static/help/configure_links.html",
- HomeLink: "http://localhost:8065",
+ HomeLink: "",
ThemeColors: ["#2389d7", "#008a17", "#dc4fad", "#ac193d", "#0072c6", "#d24726", "#ff8f32", "#82ba00", "#03b3b2", "#008299", "#4617b4", "#8c0095", "#004b8b", "#004b8b", "#570000", "#380000", "#585858", "#000000"]
};
@@ -35,4 +35,4 @@ var strings = {
TeamPlural: "teams",
Company: "company",
CompanyPlural: "companies"
-}
+};