Merge pull request #1 from rgarmsen2295/mm-1253

MM-1253
Этот коммит содержится в:
asaadmahmoodspin
2015-06-19 19:52:04 +05:00
родитель 0821b51f4e 32025e4379
Коммит 20676fd740
18 изменённых файлов: 489 добавлений и 62 удалений

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

Просмотреть файл

@@ -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/

Просмотреть файл

@@ -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 Обычный файл
Просмотреть файл

@@ -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 Исполняемый файл
Просмотреть файл

@@ -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 Обычный файл
Просмотреть файл

@@ -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>&nbsp;
<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"
}
};