Implement client connect form defaults

This commit is contained in:
Ken-Håvard Lieng 2016-01-25 01:01:37 +01:00
parent a9031eb532
commit 2ccca3a778
9 changed files with 127 additions and 57 deletions

File diff suppressed because one or more lines are too long

View File

@ -1,5 +1,6 @@
var path = require('path'); var path = require('path');
var exec = require('child_process').exec; var exec = require('child_process').exec;
var url = require('url');
var gulp = require('gulp'); var gulp = require('gulp');
var gutil = require('gulp-util'); var gutil = require('gulp-util');
@ -10,6 +11,7 @@ var gzip = require('gulp-gzip');
var concat = require('gulp-concat'); var concat = require('gulp-concat');
var cache = require('gulp-cached'); var cache = require('gulp-cached');
var express = require('express'); var express = require('express');
var proxy = require('express-http-proxy');
var webpack = require('webpack'); var webpack = require('webpack');
gulp.task('html', function() { gulp.task('html', function() {
@ -64,8 +66,8 @@ function compress() {
.pipe(gulp.dest('dist/gz')); .pipe(gulp.dest('dist/gz'));
} }
gulp.task('gzip', ['html', 'css', 'js', 'fonts'], compress); gulp.task('gzip', ['css', 'js', 'fonts'], compress);
gulp.task('gzip:dev', ['html', 'css', 'fonts'], compress); gulp.task('gzip:dev', ['css', 'fonts'], compress);
gulp.task('bindata', ['gzip', 'config'], function(cb) { gulp.task('bindata', ['gzip', 'config'], function(cb) {
exec('go-bindata -nomemcopy -nocompress -pkg assets -o ../assets/bindata.go -prefix "dist/gz" dist/gz/...', cb); exec('go-bindata -nomemcopy -nocompress -pkg assets -o ../assets/bindata.go -prefix "dist/gz" dist/gz/...', cb);
@ -75,8 +77,7 @@ gulp.task('bindata:dev', ['gzip:dev', 'config'], function(cb) {
exec('go-bindata -debug -pkg assets -o ../assets/bindata.go -prefix "dist/gz" dist/gz/...', cb); exec('go-bindata -debug -pkg assets -o ../assets/bindata.go -prefix "dist/gz" dist/gz/...', cb);
}); });
gulp.task('dev', ['html', 'css', 'fonts', 'config', 'gzip:dev', 'bindata:dev'], function() { gulp.task('dev', ['css', 'fonts', 'config', 'gzip:dev', 'bindata:dev'], function() {
gulp.watch('src/*.html', ['html']);
gulp.watch('src/css/*.css', ['css']); gulp.watch('src/css/*.css', ['css']);
var config = require('./webpack.config.dev.js'); var config = require('./webpack.config.dev.js');
@ -92,9 +93,11 @@ gulp.task('dev', ['html', 'css', 'fonts', 'config', 'gzip:dev', 'bindata:dev'],
app.use('/', express.static('dist')); app.use('/', express.static('dist'));
app.get('*', function (req, res) { app.use('*', proxy('localhost:1337', {
res.sendFile(path.join(__dirname, 'dist', 'index.html')); forwardPath: function(req, res) {
}); return url.parse(req.url).path;
}
}));
app.listen(3000, function (err) { app.listen(3000, function (err) {
if (err) { if (err) {
@ -106,6 +109,6 @@ gulp.task('dev', ['html', 'css', 'fonts', 'config', 'gzip:dev', 'bindata:dev'],
}); });
}); });
gulp.task('build', ['html', 'css', 'js', 'fonts', 'config', 'gzip', 'bindata']); gulp.task('build', ['css', 'js', 'fonts', 'config', 'gzip', 'bindata']);
gulp.task('default', ['dev']); gulp.task('default', ['dev']);

View File

@ -17,6 +17,7 @@
"eslint-loader": "^1.2.0", "eslint-loader": "^1.2.0",
"eslint-plugin-react": "^3.15.0", "eslint-plugin-react": "^3.15.0",
"express": "^4.13.3", "express": "^4.13.3",
"express-http-proxy": "^0.6.0",
"gulp": "^3.9.0", "gulp": "^3.9.0",
"gulp-autoprefixer": "3.1.0", "gulp-autoprefixer": "3.1.0",
"gulp-cached": "^1.1.0", "gulp-cached": "^1.1.0",

View File

@ -156,11 +156,11 @@ i[class^="icon-"]:before, i[class*=" icon-"]:before {
.connect { .connect {
display: flex; display: flex;
justify-content: center; justify-content: center;
align-items: center;
position: absolute; position: absolute;
top: 0; top: 0;
width: 100%; width: 100%;
bottom: 0; bottom: 0;
overflow: auto;
} }
.connect .navicon, .settings .navicon { .connect .navicon, .settings .navicon {
@ -169,6 +169,12 @@ i[class^="icon-"]:before, i[class*=" icon-"]:before {
left: 0; left: 0;
} }
.connect-form {
margin: auto 0;
padding-top: 20px;
width: 300px;
}
.connect-form h1 { .connect-form h1 {
margin-bottom: 15px; margin-bottom: 15px;
text-align: center; text-align: center;
@ -177,17 +183,19 @@ i[class^="icon-"]:before, i[class*=" icon-"]:before {
.connect-form input { .connect-form input {
display: block; display: block;
margin: 5px 0px; margin: 5px 0px;
padding: 10px; padding: 15px;
border: none; border: none;
} }
.connect-form input[type="submit"], .connect-form input[type="submit"],
.connect-form input[type="text"] { .connect-form input[type="text"],
width: 200px; .connect-form input[type="password"] {
width: 100%;
} }
.connect-form input[type="submit"] { .connect-form input[type="submit"] {
height: 50px; height: 50px;
margin-bottom: 20px;
font-family: Montserrat, sans-serif; font-family: Montserrat, sans-serif;
background: #6BB758; background: #6BB758;
color: #FFF; color: #FFF;
@ -569,4 +577,10 @@ i[class^="icon-"]:before, i[class*=" icon-"]:before {
.search { .search {
right: 0; right: 0;
} }
.connect-form {
width: 100%;
margin: auto 50px;
max-width: 400px;
}
} }

View File

@ -51,13 +51,19 @@ class Connect extends Component {
}; };
render() { render() {
const defaults = window.__ENV__.defaults;
let optionals = null; let optionals = null;
if (this.state.showOptionals) { if (this.state.showOptionals) {
optionals = ( optionals = (
<div> <div>
<input name="username" type="text" placeholder="Username" /> <input name="username" type="text" placeholder="Username" />
<input name="password" type="text" placeholder="Password" /> <input
name="password"
type="password"
placeholder="Password"
defaultValue={defaults.password}
/>
<input name="realname" type="text" placeholder="Realname" /> <input name="realname" type="text" placeholder="Realname" />
</div> </div>
); );
@ -68,13 +74,18 @@ class Connect extends Component {
<Navicon /> <Navicon />
<form ref="form" className="connect-form" onSubmit={this.handleSubmit}> <form ref="form" className="connect-form" onSubmit={this.handleSubmit}>
<h1>Connect</h1> <h1>Connect</h1>
<input name="name" type="text" placeholder="Name" defaultValue="Freenode" /> <input name="name" type="text" placeholder="Name" defaultValue={defaults.name} />
<input name="address" type="text" placeholder="Address" defaultValue="irc.freenode.net" /> <input name="address" type="text" placeholder="Address" defaultValue={defaults.address} />
<input name="nick" type="text" placeholder="Nick" /> <input name="nick" type="text" placeholder="Nick" />
<input name="channels" type="text" placeholder="Channels" /> <input
name="channels"
type="text"
placeholder="Channels"
defaultValue={defaults.channels ? defaults.channels.join(',') : null}
/>
{optionals} {optionals}
<p> <p>
<label><input name="ssl" type="checkbox" />SSL</label> <label><input name="ssl" type="checkbox" defaultChecked={defaults.ssl} />SSL</label>
<i className="icon-ellipsis" onClick={this.handleShowClick}></i> <i className="icon-ellipsis" onClick={this.handleShowClick}></i>
</p> </p>
<input type="submit" value="Connect" /> <input type="submit" value="Connect" />

View File

@ -1,15 +1,16 @@
port = 80 port = 80
verify_client_certificates = true verify_client_certificates = true
# Not implemented # Defaults for the client connect form
[defaults] [defaults]
name = "Freenode" name = "Freenode"
address = "chat.freenode.net" address = "chat.freenode.net"
password = ""
channels = [ channels = [
"#dispatch", "#dispatch",
"#go-nuts" "#go-nuts"
] ]
password = ""
ssl = true
[https] [https]
enabled = false enabled = false

41
server/index_template.go Normal file
View File

@ -0,0 +1,41 @@
package server
import (
"encoding/json"
"io"
"github.com/khlieng/dispatch/Godeps/_workspace/src/github.com/spf13/viper"
)
var (
index_start = []byte(`<!DOCTYPE html><html lang=en><head><meta charset=UTF-8><meta name=viewport content="width=device-width,initial-scale=1"><title>Dispatch</title><link href="https://fonts.googleapis.com/css?family=Montserrat:400,700|Roboto+Mono:400,700" rel=stylesheet><link href=/bundle.css rel=stylesheet></head><body><div id=root></div><script>window.__ENV__=`)
index_end = []byte(`;</script><script src=/bundle.js></script></body></html>`)
)
type connectDefaults struct {
Name string `json:"name"`
Address string `json:"address"`
Channels []string `json:"channels"`
Password string `json:"password"`
SSL bool `json:"ssl"`
}
type indexData struct {
Defaults connectDefaults `json:"defaults"`
}
func renderIndex(w io.Writer, session *Session) {
w.Write(index_start)
json.NewEncoder(w).Encode(indexData{
Defaults: connectDefaults{
Name: viper.GetString("defaults.name"),
Address: viper.GetString("defaults.address"),
Channels: viper.GetStringSlice("defaults.channels"),
Password: viper.GetString("defaults.password"),
SSL: viper.GetBool("defaults.ssl"),
},
})
w.Write(index_end)
}

View File

@ -4,6 +4,8 @@ import (
"crypto/tls" "crypto/tls"
"net" "net"
"github.com/khlieng/dispatch/Godeps/_workspace/src/github.com/spf13/viper"
"github.com/khlieng/dispatch/irc" "github.com/khlieng/dispatch/irc"
"github.com/khlieng/dispatch/storage" "github.com/khlieng/dispatch/storage"
) )
@ -24,7 +26,8 @@ func reconnectIRC() {
if cert := user.GetCertificate(); cert != nil { if cert := user.GetCertificate(); cert != nil {
i.TLSConfig = &tls.Config{ i.TLSConfig = &tls.Config{
Certificates: []tls.Certificate{*cert}, Certificates: []tls.Certificate{*cert},
InsecureSkipVerify: !viper.GetBool("verify_client_certificates"),
} }
} }

View File

@ -4,6 +4,7 @@ import (
"bytes" "bytes"
"compress/gzip" "compress/gzip"
"io/ioutil" "io/ioutil"
"log"
"net/http" "net/http"
"strconv" "strconv"
"strings" "strings"
@ -29,8 +30,7 @@ type File struct {
func serveFiles(w http.ResponseWriter, r *http.Request) { func serveFiles(w http.ResponseWriter, r *http.Request) {
if r.URL.Path == "/" { if r.URL.Path == "/" {
handleAuth(w, r) serveIndex(w, r)
serveFile(w, r, "index.html.gz", "text/html")
return return
} }
@ -46,8 +46,27 @@ func serveFiles(w http.ResponseWriter, r *http.Request) {
} }
} }
handleAuth(w, r) serveIndex(w, r)
serveFile(w, r, "index.html.gz", "text/html") }
func serveIndex(w http.ResponseWriter, r *http.Request) {
session := handleAuth(w, r)
if session == nil {
log.Println("[Auth] No session")
w.WriteHeader(500)
return
}
w.Header().Set("Content-Type", "text/html")
if strings.Contains(r.Header.Get("Accept-Encoding"), "gzip") {
w.Header().Set("Content-Encoding", "gzip")
gzw := gzip.NewWriter(w)
renderIndex(gzw, session)
gzw.Close()
} else {
renderIndex(w, session)
}
} }
func serveFile(w http.ResponseWriter, r *http.Request, path, contentType string) { func serveFile(w http.ResponseWriter, r *http.Request, path, contentType string) {