From dec6c765f53744a6f9b265eaf3ecb56d9cef1331 Mon Sep 17 00:00:00 2001 From: Christopher Speller Date: Wed, 17 Jun 2015 08:39:33 -0400 Subject: Resurrecting config_docker.json. Moving docker related files to docker directory. Added copyright info. --- Dockerfile | 8 +-- config/config.json | 4 +- config/config_docker.json | 85 ++++++++++++++++++++++++++++++++ config/main.cf | 41 ---------------- docker-entry.sh | 120 --------------------------------------------- docker/docker-entry.sh | 122 ++++++++++++++++++++++++++++++++++++++++++++++ docker/main.cf | 28 +++++++++++ utils/config_test.go | 4 +- 8 files changed, 243 insertions(+), 169 deletions(-) create mode 100644 config/config_docker.json delete mode 100644 config/main.cf delete mode 100755 docker-entry.sh create mode 100755 docker/docker-entry.sh create mode 100644 docker/main.cf diff --git a/Dockerfile b/Dockerfile index da57550c0..5c389c056 100644 --- a/Dockerfile +++ b/Dockerfile @@ -1,3 +1,5 @@ +# Copyright (c) 2015 Spinpunch, Inc. All Rights Reserved. +# See License.txt for license information. FROM ubuntu:14.04 # Install Dependancies @@ -83,15 +85,15 @@ RUN wget http://download.redis.io/redis-stable.tar.gz; \ ADD . /go/src/github.com/mattermost/platform # Insert postfix config -ADD ./config/main.cf /etc/postfix/ +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-entry.sh -ENTRYPOINT /go/src/github.com/mattermost/platform/docker-entry.sh +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/config/config.json b/config/config.json index 3d2c26716..1b844c259 100644 --- a/config/config.json +++ b/config/config.json @@ -9,7 +9,7 @@ }, "ServiceSettings": { "SiteName": "Mattermost Preview", - "Domain": "", + "Domain": "xxxxxxmustbefilledin.com", "Mode" : "dev", "AllowTesting" : false, "UseSSL": false, @@ -56,7 +56,7 @@ "EmailSettings": { "SMTPUsername": "", "SMTPPassword": "", - "SMTPServer": "localhost:25", + "SMTPServer": "", "UseTLS": false, "FeedbackEmail": "feedback@xxxxxxmustbefilledin.com", "FeedbackName": "", 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/config/main.cf b/config/main.cf deleted file mode 100644 index 72eba333f..000000000 --- a/config/main.cf +++ /dev/null @@ -1,41 +0,0 @@ -# See /usr/share/postfix/main.cf.dist for a commented, more complete version - - -# Debian specific: Specifying a file name will cause the first -# line of that file to be used as the name. The Debian default -# is /etc/mailname. -myorigin = mattermost.com -myhostname = mattermost.com - -smtpd_banner = $myhostname ESMTP $mail_name (Ubuntu) -biff = no - -# appending .domain is the MUA's job. -append_dot_mydomain = no - -# Uncomment the next line to generate "delayed mail" warnings -#delay_warning_time = 4h - -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 - -# See /usr/share/doc/postfix/TLS_README.gz in the postfix-doc package for -# information on enabling SSL in the smtp client. - -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/docker-entry.sh b/docker-entry.sh deleted file mode 100755 index db6ccaa18..000000000 --- a/docker-entry.sh +++ /dev/null @@ -1,120 +0,0 @@ -#!/bin/bash - -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.json & - -echo starting compass watch -cd /go/src/github.com/mattermost/platform/web/sass-files && compass watch 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/utils/config_test.go b/utils/config_test.go index f6746f3ac..9067dc647 100644 --- a/utils/config_test.go +++ b/utils/config_test.go @@ -4,7 +4,7 @@ package utils import ( - //"os" + "os" "testing" ) @@ -12,7 +12,6 @@ func TestConfig(t *testing.T) { LoadConfig("config.json") } -/* func TestEnvOverride(t *testing.T) { os.Setenv("MATTERMOST_DOMAIN", "testdomain.com") @@ -26,4 +25,3 @@ func TestEnvOverride(t *testing.T) { t.Fail() } } -*/ -- cgit v1.2.3-1-g7c22 From aba56724a5a2bac818b583aa59dd7c4d7445d964 Mon Sep 17 00:00:00 2001 From: Christopher Speller Date: Wed, 17 Jun 2015 11:50:51 -0400 Subject: Adding check of email configuation settings when config file is loaded --- utils/config.go | 5 +++ utils/mail.go | 98 ++++++++++++++++++++++++++++++++++++++------------------- 2 files changed, 71 insertions(+), 32 deletions(-) diff --git a/utils/config.go b/utils/config.go index 745887c70..418041706 100644 --- a/utils/config.go +++ b/utils/config.go @@ -222,6 +222,11 @@ func LoadConfig(fileName string) { 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/mail.go b/utils/mail.go index bf1cc9d46..2fb7f801d 100644 --- a/utils/mail.go +++ b/utils/mail.go @@ -13,32 +13,27 @@ import ( "net/smtp" ) -func SendMail(to, subject, body string) *model.AppError { - - fromMail := mail.Address{"", Cfg.EmailSettings.FeedbackEmail} - toMail := mail.Address{"", to} - - headers := make(map[string]string) - headers["From"] = fromMail.String() - headers["To"] = toMail.String() - headers["Subject"] = subject - headers["MIME-version"] = "1.0" - headers["Content-Type"] = "text/html" - - message := "" - for k, v := range headers { - message += fmt.Sprintf("%s: %s\r\n", k, v) - } - message += "\r\n" + body + "" - +func CheckMailSettings() *model.AppError { if len(Cfg.EmailSettings.SMTPServer) == 0 { - l4g.Warn("Skipping sending of email because EmailSettings are not configured") - return nil + 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() - host, _, _ := net.SplitHostPort(Cfg.EmailSettings.SMTPServer) + return nil +} - auth := smtp.PlainAuth("", Cfg.EmailSettings.SMTPUsername, Cfg.EmailSettings.SMTPPassword, host) +func connectToSMTPServer() (net.Conn, *model.AppError) { + host, _, _ := net.SplitHostPort(Cfg.EmailSettings.SMTPServer) var conn net.Conn var err error @@ -51,38 +46,77 @@ func SendMail(to, subject, body string) *model.AppError { conn, err = tls.Dial("tcp", Cfg.EmailSettings.SMTPServer, tlsconfig) if err != nil { - return model.NewAppError("SendMail", "Failed to open TLS connection", err.Error()) + 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 model.NewAppError("SendMail", "Failed to open connection", err.Error()) + return nil, model.NewAppError("SendMail", "Failed to open connection", err.Error()) } } - defer conn.Close() + 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 model.NewAppError("SendMail", "Failed to open TLS connection", err.Error()) + return nil, model.NewAppError("SendMail", "Failed to open TLS connection", err.Error()) } - defer c.Quit() - defer c.Close() - // 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 model.NewAppError("SendMail", "Failed to authenticate on SMTP server", err.Error()) + 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} + toMail := mail.Address{"", to} + + headers := make(map[string]string) + headers["From"] = fromMail.String() + headers["To"] = toMail.String() + headers["Subject"] = subject + headers["MIME-version"] = "1.0" + headers["Content-Type"] = "text/html" + + message := "" + for k, v := range headers { + message += fmt.Sprintf("%s: %s\r\n", k, v) + } + message += "\r\n" + body + "" + + if len(Cfg.EmailSettings.SMTPServer) == 0 { + l4g.Warn("Skipping sending of email because EmailSettings are not configured") + return nil + } + + conn, err1 := connectToSMTPServer() + if err1 != nil { + return err1 + } + defer conn.Close() + + c, err2 := newSMTPClient(conn) + if err2 != nil { + return err2 + } + defer c.Quit() + defer c.Close() - 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()) } -- cgit v1.2.3-1-g7c22 From 5a0389bc2175aa1a24581d7a36353c92fde4ed79 Mon Sep 17 00:00:00 2001 From: JoramWilander Date: Wed, 17 Jun 2015 12:25:41 -0400 Subject: fix an auto-complete bug for mentions --- web/react/components/textbox.jsx | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) 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; } -- cgit v1.2.3-1-g7c22