99
Dockerfile
Обычный файл
99
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
|
||||
11
NOTICE.txt
11
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/
|
||||
|
||||
33
README.md
33
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**
|
||||
|
||||
@@ -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": "",
|
||||
|
||||
85
config/config_docker.json
Обычный файл
85
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"
|
||||
}
|
||||
}
|
||||
122
docker/docker-entry.sh
Исполняемый файл
122
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
|
||||
28
docker/main.cf
Обычный файл
28
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
|
||||
@@ -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)
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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()
|
||||
}
|
||||
}
|
||||
|
||||
@@ -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())
|
||||
}
|
||||
|
||||
|
||||
@@ -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>
|
||||
|
||||
@@ -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);
|
||||
}
|
||||
|
||||
|
||||
@@ -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>
|
||||
<button className="btn-primary btn" onClick={this.submitNext}>Next<i className="glyphicon glyphicon-chevron-right"></i></button>
|
||||
</div>
|
||||
|
||||
@@ -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" />
|
||||
|
||||
@@ -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;
|
||||
}
|
||||
|
||||
|
||||
@@ -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(".");
|
||||
}
|
||||
|
||||
@@ -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"
|
||||
}
|
||||
};
|
||||
|
||||
Ссылка в новой задаче
Block a user