Initial commit
This commit is contained in:
commit
10993b9209
28 files changed
+887
No files matched your search
@@ -0,0 +1,3 @@
|
|||||||
|
mini-beieli-web
|
||||||
|
nohup.out
|
||||||
|
database/
|
||||||
@@ -0,0 +1,7 @@
|
|||||||
|
# mini-beieli-web - Bienenstock Ueberwachung
|
||||||
|
|
||||||
|
Webapplikation, geschrieben in Golang.
|
||||||
|
|
||||||
|
Autor: Joerg Lehmann, nbit Informatik GmbH
|
||||||
|
|
||||||
|
|
||||||
@@ -0,0 +1,129 @@
|
|||||||
|
package main
|
||||||
|
|
||||||
|
import (
|
||||||
|
"github.com/gorilla/securecookie"
|
||||||
|
"net/http"
|
||||||
|
"fmt"
|
||||||
|
"crypto/md5"
|
||||||
|
"encoding/hex"
|
||||||
|
)
|
||||||
|
|
||||||
|
// cookie handling
|
||||||
|
|
||||||
|
var cookieHandler = securecookie.New(
|
||||||
|
securecookie.GenerateRandomKey(64),
|
||||||
|
securecookie.GenerateRandomKey(32))
|
||||||
|
|
||||||
|
func getUserName(request *http.Request) (userName string) {
|
||||||
|
if cookie, err := request.Cookie("session"); err == nil {
|
||||||
|
cookieValue := make(map[string]string)
|
||||||
|
if err = cookieHandler.Decode("session", cookie.Value, &cookieValue); err == nil {
|
||||||
|
userName = cookieValue["name"]
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return userName
|
||||||
|
}
|
||||||
|
|
||||||
|
func getUserNameHash(request *http.Request) (userName string) {
|
||||||
|
if cookie, err := request.Cookie("session"); err == nil {
|
||||||
|
cookieValue := make(map[string]string)
|
||||||
|
if err = cookieHandler.Decode("session", cookie.Value, &cookieValue); err == nil {
|
||||||
|
userName = cookieValue["name"]
|
||||||
|
}
|
||||||
|
}
|
||||||
|
hasher := md5.New()
|
||||||
|
hasher.Write([]byte(userName))
|
||||||
|
return hex.EncodeToString(hasher.Sum(nil))
|
||||||
|
}
|
||||||
|
|
||||||
|
func setSession(userName string, response http.ResponseWriter) {
|
||||||
|
value := map[string]string{
|
||||||
|
"name": userName,
|
||||||
|
}
|
||||||
|
if encoded, err := cookieHandler.Encode("session", value); err == nil {
|
||||||
|
cookie := &http.Cookie{
|
||||||
|
Name: "session",
|
||||||
|
Value: encoded,
|
||||||
|
Path: "/",
|
||||||
|
}
|
||||||
|
http.SetCookie(response, cookie)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
func clearSession(response http.ResponseWriter) {
|
||||||
|
cookie := &http.Cookie{
|
||||||
|
Name: "session",
|
||||||
|
Value: "",
|
||||||
|
Path: "/",
|
||||||
|
MaxAge: -1,
|
||||||
|
}
|
||||||
|
http.SetCookie(response, cookie)
|
||||||
|
}
|
||||||
|
|
||||||
|
// login handler
|
||||||
|
|
||||||
|
func loginHandler(response http.ResponseWriter, request *http.Request) {
|
||||||
|
name := request.FormValue("email")
|
||||||
|
pass := request.FormValue("password")
|
||||||
|
redirectTarget := "/invalid_login.html"
|
||||||
|
//if name != "" && pass != "" {
|
||||||
|
if checkLoginCredentials(name,pass) {
|
||||||
|
// .. check credentials ..
|
||||||
|
logit(fmt.Sprintf("loginHandler: successful login for User %s",name))
|
||||||
|
setSession(name, response)
|
||||||
|
updateLoginTime(name)
|
||||||
|
redirectTarget = "/scales.html"
|
||||||
|
} else {
|
||||||
|
logit(fmt.Sprintf("loginHandler: invalid login for User %s",name))
|
||||||
|
}
|
||||||
|
http.Redirect(response, request, redirectTarget, 302)
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
// resetPassword handler
|
||||||
|
|
||||||
|
func resetPasswordHandler(response http.ResponseWriter, request *http.Request) {
|
||||||
|
name := request.FormValue("email")
|
||||||
|
pass := request.FormValue("password")
|
||||||
|
redirectTarget := "/"
|
||||||
|
logit(fmt.Sprintf("resetPasswordHandler: request for User %s",name))
|
||||||
|
if name != "" && pass != "" {
|
||||||
|
if checkUserAvailable(name) {
|
||||||
|
http.Redirect(response, request, "/user_does_not_exist.html", 302)
|
||||||
|
} else {
|
||||||
|
updateUser(name,pass)
|
||||||
|
http.Redirect(response, request, redirectTarget, 302)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
http.Redirect(response, request, "/error_reset_password.html",302)
|
||||||
|
}
|
||||||
|
|
||||||
|
// setPassword handler
|
||||||
|
|
||||||
|
func setPasswordHandler(response http.ResponseWriter, request *http.Request) {
|
||||||
|
name := getUserName(request)
|
||||||
|
pass := request.FormValue("password")
|
||||||
|
if name != "" && pass != "" {
|
||||||
|
if checkUserAvailable(name) {
|
||||||
|
http.Redirect(response, request, "/user_does_not_exist.html", 302)
|
||||||
|
} else {
|
||||||
|
updateUser(name,pass)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// logout handler
|
||||||
|
|
||||||
|
func logoutHandler(response http.ResponseWriter, request *http.Request) {
|
||||||
|
clearSession(response)
|
||||||
|
http.Redirect(response, request, "/", 302)
|
||||||
|
}
|
||||||
|
|
||||||
|
// confirm handler
|
||||||
|
|
||||||
|
func confirmHandler(response http.ResponseWriter, request *http.Request) {
|
||||||
|
confirm_id := request.URL.Query().Get("id")
|
||||||
|
logit(fmt.Sprintf("Confirm ID: %s\n",confirm_id))
|
||||||
|
confirmUser(confirm_id)
|
||||||
|
http.Redirect(response, request, "/", 302)
|
||||||
|
}
|
||||||
@@ -0,0 +1,9 @@
|
|||||||
|
package main
|
||||||
|
|
||||||
|
import (
|
||||||
|
"log"
|
||||||
|
)
|
||||||
|
|
||||||
|
func logit(log_message string) {
|
||||||
|
log.Println(log_message)
|
||||||
|
}
|
||||||
@@ -0,0 +1,44 @@
|
|||||||
|
package main
|
||||||
|
|
||||||
|
import (
|
||||||
|
"log"
|
||||||
|
"bytes"
|
||||||
|
"net/smtp"
|
||||||
|
)
|
||||||
|
|
||||||
|
func sendEmail(username,confirm_id string) {
|
||||||
|
c, err := smtp.Dial("127.0.0.1:25")
|
||||||
|
if err != nil {
|
||||||
|
log.Fatal(err)
|
||||||
|
}
|
||||||
|
defer c.Close()
|
||||||
|
// Set the sender and recipient.
|
||||||
|
c.Mail("register@mini-beieli.ch")
|
||||||
|
c.Rcpt(username)
|
||||||
|
// Send the email body.
|
||||||
|
wc, err := c.Data()
|
||||||
|
if err != nil {
|
||||||
|
log.Fatal(err)
|
||||||
|
}
|
||||||
|
defer wc.Close()
|
||||||
|
mail_message := "To: " + username + `
|
||||||
|
Subject: Passwortaenderung auf https://mini-beieli.ch, bitte bestaetigen
|
||||||
|
|
||||||
|
Lieber Benutzer von mini-beieli.ch
|
||||||
|
|
||||||
|
Sie haben soeben eine Passwortaenderung veranlasst. Bitte klicken Sie folgenden Link,
|
||||||
|
um die Registration abzuschliessen:
|
||||||
|
|
||||||
|
https://mini-beieli.ch/confirm?id=` + confirm_id + `
|
||||||
|
|
||||||
|
Bitte ignorieren Sie diese Meldung, falls die Aenderung nicht von Ihnen angefordert wurde!
|
||||||
|
|
||||||
|
Mit freundlichen Grüssen
|
||||||
|
--
|
||||||
|
mini-beieli.ch`
|
||||||
|
|
||||||
|
buf := bytes.NewBufferString(mail_message)
|
||||||
|
if _, err = buf.WriteTo(wc); err != nil {
|
||||||
|
log.Fatal(err)
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -0,0 +1,91 @@
|
|||||||
|
package main
|
||||||
|
|
||||||
|
import (
|
||||||
|
"html/template"
|
||||||
|
"net/http"
|
||||||
|
"os"
|
||||||
|
"path"
|
||||||
|
"time"
|
||||||
|
)
|
||||||
|
|
||||||
|
type AccountData struct {
|
||||||
|
Full_name string
|
||||||
|
Phone string
|
||||||
|
Address string
|
||||||
|
Zip string
|
||||||
|
City string
|
||||||
|
}
|
||||||
|
|
||||||
|
type Scale struct {
|
||||||
|
Beielipi_id string
|
||||||
|
Beielipi_alias string
|
||||||
|
Id string
|
||||||
|
Alias string
|
||||||
|
My_sms_number string
|
||||||
|
Sms_alarm string
|
||||||
|
Last_alarm string
|
||||||
|
}
|
||||||
|
|
||||||
|
func serveTemplate(w http.ResponseWriter, r *http.Request) {
|
||||||
|
logit("Called URL: "+r.URL.Path)
|
||||||
|
// wennn kein File angegeben ist: index.html
|
||||||
|
if r.URL.Path == "/" {
|
||||||
|
r.URL.Path = "/index.html"
|
||||||
|
}
|
||||||
|
lp := path.Join("templates", "layout.html")
|
||||||
|
fp := path.Join("snippets", r.URL.Path)
|
||||||
|
|
||||||
|
// Return a 404 if the template doesn't exist
|
||||||
|
_, err := os.Stat(fp)
|
||||||
|
if err != nil {
|
||||||
|
if os.IsNotExist(err) {
|
||||||
|
logit("URL not found: " + fp)
|
||||||
|
fp = path.Join("snippets", "404.html")
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
tmpl, err := template.ParseFiles(lp, fp)
|
||||||
|
if err != nil {
|
||||||
|
// Log the detailed error
|
||||||
|
logit(err.Error())
|
||||||
|
// Return a generic "Internal Server Error" message
|
||||||
|
http.Error(w, http.StatusText(500), 500)
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
var userName = getUserName(r)
|
||||||
|
|
||||||
|
t := time.Now()
|
||||||
|
var datetimestring = t.Format("20060102150405")
|
||||||
|
data := struct {
|
||||||
|
UserName string
|
||||||
|
DateTimeString string
|
||||||
|
} {
|
||||||
|
userName,
|
||||||
|
datetimestring,
|
||||||
|
}
|
||||||
|
|
||||||
|
if err := tmpl.ExecuteTemplate(w, "layout", &data); err != nil {
|
||||||
|
logit(err.Error())
|
||||||
|
http.Error(w, http.StatusText(500), 500)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
func main() {
|
||||||
|
initDB()
|
||||||
|
defer closeDB()
|
||||||
|
fs := http.FileServer(http.Dir("static"))
|
||||||
|
http.Handle("/static/", http.StripPrefix("/static/", fs))
|
||||||
|
http.Handle("/favicon.ico", fs)
|
||||||
|
http.HandleFunc("/", serveTemplate)
|
||||||
|
|
||||||
|
http.HandleFunc("/login", loginHandler)
|
||||||
|
http.HandleFunc("/reset_password", resetPasswordHandler)
|
||||||
|
http.HandleFunc("/set_password", setPasswordHandler)
|
||||||
|
http.HandleFunc("/logout", logoutHandler)
|
||||||
|
http.HandleFunc("/confirm", confirmHandler)
|
||||||
|
|
||||||
|
logit("Starting Web Application...")
|
||||||
|
http.ListenAndServe("127.0.0.1:4000", nil)
|
||||||
|
logit("Terminating Web Application...")
|
||||||
|
}
|
||||||
+235
@@ -0,0 +1,235 @@
|
|||||||
|
package main
|
||||||
|
|
||||||
|
import (
|
||||||
|
"time"
|
||||||
|
"encoding/json"
|
||||||
|
"crypto/rand"
|
||||||
|
"golang.org/x/crypto/bcrypt"
|
||||||
|
"github.com/gomodule/redigo/redis"
|
||||||
|
)
|
||||||
|
|
||||||
|
var globalPool *redis.Pool
|
||||||
|
var globalConn redis.Conn
|
||||||
|
|
||||||
|
|
||||||
|
const userPrefix string = "user:"
|
||||||
|
const confirmPrefix string = "confirm:"
|
||||||
|
|
||||||
|
func newPool() *redis.Pool {
|
||||||
|
return &redis.Pool{
|
||||||
|
// Maximum number of idle connections in the pool.
|
||||||
|
MaxIdle: 80,
|
||||||
|
// max number of connections
|
||||||
|
MaxActive: 12000,
|
||||||
|
// Dial is an application supplied function for creating and
|
||||||
|
// configuring a connection.
|
||||||
|
Dial: func() (redis.Conn, error) {
|
||||||
|
c, err := redis.Dial("tcp", ":6379")
|
||||||
|
if err != nil {
|
||||||
|
panic(err.Error())
|
||||||
|
}
|
||||||
|
return c, err
|
||||||
|
},
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// ping tests connectivity for redis (PONG should be returned)
|
||||||
|
func ping(c redis.Conn) error {
|
||||||
|
// Send PING command to Redis
|
||||||
|
// PING command returns a Redis "Simple String"
|
||||||
|
// Use redis.String to convert the interface type to string
|
||||||
|
s, err := redis.String(c.Do("PING"))
|
||||||
|
if err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
|
||||||
|
logit("PING Response = "+s)
|
||||||
|
// Output: PONG
|
||||||
|
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
|
||||||
|
// User is a simple user struct for this example
|
||||||
|
type User struct {
|
||||||
|
Email string `json:"email"`
|
||||||
|
Password string `json:"password"`
|
||||||
|
NewPassword string `json:"new_password"`
|
||||||
|
ConfirmId string `json:"confirm_id"`
|
||||||
|
LastLogin string `json:"last_login"`
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
func setStruct(c redis.Conn, usr User) error {
|
||||||
|
|
||||||
|
// serialize User object to JSON
|
||||||
|
json, err := json.Marshal(usr)
|
||||||
|
if err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
|
||||||
|
// SET object
|
||||||
|
_, err = c.Do("SET", userPrefix+usr.Email, json)
|
||||||
|
if err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
|
||||||
|
func getStruct(c redis.Conn, username string) (User, error) {
|
||||||
|
|
||||||
|
usr := User{}
|
||||||
|
s, err := redis.String(c.Do("GET", userPrefix+username))
|
||||||
|
if err == redis.ErrNil {
|
||||||
|
logit("User does not exist:"+username)
|
||||||
|
} else if err != nil {
|
||||||
|
return usr, err
|
||||||
|
}
|
||||||
|
|
||||||
|
err = json.Unmarshal([]byte(s), &usr)
|
||||||
|
|
||||||
|
return usr, nil
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
func initDB() {
|
||||||
|
|
||||||
|
// newPool returns a pointer to a redis.Pool
|
||||||
|
pool := newPool()
|
||||||
|
// get a connection from the pool (redis.Conn)
|
||||||
|
conn := pool.Get()
|
||||||
|
|
||||||
|
globalPool = pool
|
||||||
|
globalConn = conn
|
||||||
|
|
||||||
|
// wir machen einen Connection Test
|
||||||
|
ping(globalConn)
|
||||||
|
|
||||||
|
// Wir legen einen initialen Admin User an, falls es diesen noch nicht gibt
|
||||||
|
if checkUserAvailable("joerg.lehmann@nbit.ch") {
|
||||||
|
insertUser("joerg.lehmann@nbit.ch","changeme123","Y");
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
func closeDB() {
|
||||||
|
globalConn.Close()
|
||||||
|
globalPool.Close()
|
||||||
|
}
|
||||||
|
|
||||||
|
func checkUserAvailable(username string) bool {
|
||||||
|
logit("checkUserAvailable: User: "+username)
|
||||||
|
_, err := redis.String(globalConn.Do("GET", userPrefix+username))
|
||||||
|
if (err == redis.ErrNil) {
|
||||||
|
logit("User does not exist and is therefore available:"+username)
|
||||||
|
return true
|
||||||
|
} else if err != nil {
|
||||||
|
logit("checkUserAvailable: Error to query Key Value Store")
|
||||||
|
return false
|
||||||
|
}
|
||||||
|
return false
|
||||||
|
}
|
||||||
|
|
||||||
|
func randString(n int) string {
|
||||||
|
const alphanum = "0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz"
|
||||||
|
var bytes = make([]byte, n)
|
||||||
|
rand.Read(bytes)
|
||||||
|
for i, b := range bytes {
|
||||||
|
bytes[i] = alphanum[b % byte(len(alphanum))]
|
||||||
|
}
|
||||||
|
return string(bytes)
|
||||||
|
}
|
||||||
|
|
||||||
|
func insertUser(username,password,is_admin string) {
|
||||||
|
logit("insertUser: "+username)
|
||||||
|
pwd := []byte(password)
|
||||||
|
hashedPassword,err := bcrypt.GenerateFromPassword(pwd, bcrypt.DefaultCost)
|
||||||
|
if err != nil {
|
||||||
|
logit("insertUser: Error with bcrypt.GenerateFromPassword, User: "+username)
|
||||||
|
return
|
||||||
|
}
|
||||||
|
confirm_id := ""
|
||||||
|
|
||||||
|
_, err = globalConn.Do("HMSET", userPrefix+username, "password", string(hashedPassword), "new_password", string(hashedPassword), "confirm_id", confirm_id, "last_login", "")
|
||||||
|
|
||||||
|
if err != nil {
|
||||||
|
logit("insertUser: Error inserting User: "+username)
|
||||||
|
return
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
func updateUser(username,password string) {
|
||||||
|
logit("updateUser: "+username)
|
||||||
|
pwd := []byte(password)
|
||||||
|
hashedPassword,err := bcrypt.GenerateFromPassword(pwd, bcrypt.DefaultCost)
|
||||||
|
if err != nil {
|
||||||
|
logit("updateUser: Error with bcrypt.GenerateFromPassword, User: "+username)
|
||||||
|
return
|
||||||
|
}
|
||||||
|
confirm_id := randString(30)
|
||||||
|
|
||||||
|
_, err = globalConn.Do("HMSET", userPrefix+username, "new_password", string(hashedPassword), "confirm_id", confirm_id)
|
||||||
|
if err != nil {
|
||||||
|
logit("updateUser: Error updateing User: "+username)
|
||||||
|
return
|
||||||
|
}
|
||||||
|
_, err = globalConn.Do("SET", confirmPrefix+confirm_id,username)
|
||||||
|
if err != nil {
|
||||||
|
logit("updateUser: Error inserting confirm_id: "+confirm_id+": "+username)
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
sendEmail(username,confirm_id)
|
||||||
|
}
|
||||||
|
|
||||||
|
func checkLoginCredentials(username,password string) bool {
|
||||||
|
logit("checkLoginCredentials: called with username,password: "+username+","+password)
|
||||||
|
pwd, err := redis.String(globalConn.Do("HGET", userPrefix+username, "password"))
|
||||||
|
if err == nil {
|
||||||
|
cid, err := redis.String(globalConn.Do("HGET", userPrefix+username, "confirm_id"))
|
||||||
|
if err == nil {
|
||||||
|
logit("checkLoginCredentials: cid: "+cid)
|
||||||
|
if !(err != nil && cid != "") {
|
||||||
|
logit("checkLoginCredentials: pwd: "+pwd)
|
||||||
|
if err != nil {
|
||||||
|
return false
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
hashedPassword := []byte(pwd)
|
||||||
|
err = bcrypt.CompareHashAndPassword(hashedPassword, []byte(password))
|
||||||
|
return err == nil
|
||||||
|
}
|
||||||
|
|
||||||
|
func updateLoginTime(username string) {
|
||||||
|
_, err := globalConn.Do("HSET", userPrefix+username, "last_login", time.Now().UTC().Format("2006-01-02 15:04:05"))
|
||||||
|
if err != nil {
|
||||||
|
logit("updateUser: Error updateing User: "+username)
|
||||||
|
return
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
func confirmUser(confirm_id string) {
|
||||||
|
u, err := redis.String(globalConn.Do("GET", confirmPrefix+confirm_id))
|
||||||
|
if err != nil {
|
||||||
|
logit("confirmUser: Error with searching confirm_id: "+confirm_id)
|
||||||
|
return
|
||||||
|
}
|
||||||
|
new_password, err := redis.String(globalConn.Do("HGET", userPrefix+u, "new_password"))
|
||||||
|
if err != nil {
|
||||||
|
logit("confirmUser: Error with getting new_password: "+u)
|
||||||
|
return
|
||||||
|
}
|
||||||
|
_, err = globalConn.Do("HMSET", userPrefix+u, "confirm_id", "", "password", new_password)
|
||||||
|
if err != nil {
|
||||||
|
logit("confirmUser: Error updateing User: "+u)
|
||||||
|
return
|
||||||
|
}
|
||||||
|
_, err = globalConn.Do("DEL", confirmPrefix+confirm_id)
|
||||||
|
if err != nil {
|
||||||
|
logit("confirmUser: Error deleting confirm_id: "+confirm_id)
|
||||||
|
return
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -0,0 +1,5 @@
|
|||||||
|
{{define "body_content"}}
|
||||||
|
<div class="notification is-danger">
|
||||||
|
<strong>Diese Seite existiert nicht</strong>
|
||||||
|
</div>
|
||||||
|
{{end}}
|
||||||
@@ -0,0 +1,9 @@
|
|||||||
|
{{define "body_content"}}
|
||||||
|
<p class="title is-4">Kontakt</p>
|
||||||
|
<p>nbit Informatik GmbH<br />
|
||||||
|
Kirchweg 2<br />
|
||||||
|
3510 Konolfingen<br />
|
||||||
|
<br />
|
||||||
|
+41 31 792 00 40<br />
|
||||||
|
<a href='mailto:i%6Efo@%6Ebit.%63h'>info@nbit.ch</a>
|
||||||
|
{{end}}
|
||||||
@@ -0,0 +1,28 @@
|
|||||||
|
{{define "header_additions"}}
|
||||||
|
{{end}}
|
||||||
|
{{define "body_content"}}
|
||||||
|
<p class="title is-4">Die etwas andere Bienenstockwaage...</p>
|
||||||
|
<article class="message is-danger">
|
||||||
|
<div class="message-body">
|
||||||
|
Aktuell noch in Entwicklung, kommen Sie später noch einmal vorbei...
|
||||||
|
</div>
|
||||||
|
</article>
|
||||||
|
{{ if ne .UserName "" }}
|
||||||
|
<p>
|
||||||
|
<strong>Ich will weitere bestellen!</strong>
|
||||||
|
<span class="icon"><i class="fa fa-arrow-right"></i></span>
|
||||||
|
Hier geht's zum <a href="/order.html">Bestellformular</a>
|
||||||
|
</p>
|
||||||
|
{{ else }}
|
||||||
|
<p>
|
||||||
|
<strong>Ich will auch eine!</strong>
|
||||||
|
<span class="icon"><i class="fa fa-arrow-right"></i></span>
|
||||||
|
Hier geht's zum <a href="/order.html">Bestellformular</a>
|
||||||
|
</p>
|
||||||
|
<p> </p>
|
||||||
|
<p>
|
||||||
|
<strong>Ich habe bereits eine (oder mehrere)</strong>
|
||||||
|
<span class="icon"><i class="fa fa-arrow-right"></i></span>
|
||||||
|
Hier geht's zum <a href="/login.html">Login</a>
|
||||||
|
{{end}}
|
||||||
|
{{end}}
|
||||||
@@ -0,0 +1,5 @@
|
|||||||
|
{{define "body_content"}}
|
||||||
|
<div class="notification is-danger">
|
||||||
|
<strong>Ungültiges Login!</strong>
|
||||||
|
</div>
|
||||||
|
{{end}}
|
||||||
@@ -0,0 +1,46 @@
|
|||||||
|
{{define "body_content"}}
|
||||||
|
{{ if ne .UserName "" }}
|
||||||
|
Sie sind bereits eingeloggt!
|
||||||
|
{{ else }}
|
||||||
|
<form class="form-signin" id="login-form" action="/login">
|
||||||
|
<div class="column is-auto">
|
||||||
|
<div class="columns is-centered">
|
||||||
|
<div class="column is-4">
|
||||||
|
<h1 class="title">Login</h1>
|
||||||
|
<div class="field">
|
||||||
|
<p class="control has-icons-left has-icons-right">
|
||||||
|
<input id="email" name="email" class="input is-success is-focused" type="text" placeholder="Email">
|
||||||
|
<span class="icon is-small is-left">
|
||||||
|
<i class="fa fa-envelope"></i>
|
||||||
|
</span>
|
||||||
|
<span class="icon is-small is-right">
|
||||||
|
<i class="fa fa-check"></i>
|
||||||
|
</span>
|
||||||
|
</p>
|
||||||
|
</div>
|
||||||
|
<div class="field">
|
||||||
|
<p class="control has-icons-left has-icons-right">
|
||||||
|
<input id="password" name="password" class="input" type="password" placeholder="Password">
|
||||||
|
<span class="icon is-small is-left">
|
||||||
|
<i class="fa fa-lock"></i>
|
||||||
|
</span>
|
||||||
|
<span class="icon is-small is-right">
|
||||||
|
<i class="fa fa-check"></i>
|
||||||
|
</span>
|
||||||
|
</p>
|
||||||
|
</div>
|
||||||
|
<div class="has-text-centered">
|
||||||
|
<a href="/reset_password.html">Passwort vergessen?</a><br/>
|
||||||
|
</div>
|
||||||
|
<br>
|
||||||
|
<div id="errorbox" class="notification is-danger is-size-7-mobile" style="display: none;">
|
||||||
|
</div>
|
||||||
|
<div class="has-text-centered">
|
||||||
|
<input id="login-button" name="login-button" type="submit" class="form-button button is-primary is-centered" value="Anmelden"></input>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</form>
|
||||||
|
{{end}}
|
||||||
|
{{end}}
|
||||||
@@ -0,0 +1,8 @@
|
|||||||
|
{{define "body_content"}}
|
||||||
|
<p class="title is-4">Bestellformular</p>
|
||||||
|
<article class="message is-danger">
|
||||||
|
<div class="message-body">
|
||||||
|
Aktuell noch in Entwicklung, kommen Sie später noch einmal vorbei...
|
||||||
|
</div>
|
||||||
|
</article>
|
||||||
|
{{end}}
|
||||||
@@ -0,0 +1,46 @@
|
|||||||
|
{{define "body_content"}}
|
||||||
|
{{ if ne .UserName "" }}
|
||||||
|
Sie sind bereits eingeloggt!
|
||||||
|
{{ else }}
|
||||||
|
<p class="title is-4">Passwort zurücksetzen</p>
|
||||||
|
<div class="notification is-info">
|
||||||
|
<p>Hier können Sie ein neues Passwort setzen. Sie erhalten anschliessend eine Meldung zur Bestätigung zugesendet. Das neue Passwort wird erst gültig, wenn Sie die Bestätigung durchgeführt haben.</p>
|
||||||
|
</div>
|
||||||
|
<form class="form-signin" id="reset-password-form" action="/reset_password">
|
||||||
|
<div class="column is-auto">
|
||||||
|
<div class="columns is-centered">
|
||||||
|
<div class="column is-4">
|
||||||
|
<div class="field">
|
||||||
|
<p class="control has-icons-left has-icons-right">
|
||||||
|
<input id="email" name="email" class="input is-success is-focused" type="text" placeholder="Email">
|
||||||
|
<span class="icon is-small is-left">
|
||||||
|
<i class="fa fa-envelope"></i>
|
||||||
|
</span>
|
||||||
|
<span class="icon is-small is-right">
|
||||||
|
<i class="fa fa-check"></i>
|
||||||
|
</span>
|
||||||
|
</p>
|
||||||
|
</div>
|
||||||
|
<div class="field">
|
||||||
|
<p class="control has-icons-left has-icons-right">
|
||||||
|
<input id="password" name="password" class="input" type="password" placeholder="Password">
|
||||||
|
<span class="icon is-small is-left">
|
||||||
|
<i class="fa fa-lock"></i>
|
||||||
|
</span>
|
||||||
|
<span class="icon is-small is-right">
|
||||||
|
<i class="fa fa-check"></i>
|
||||||
|
</span>
|
||||||
|
</p>
|
||||||
|
</div>
|
||||||
|
<br>
|
||||||
|
<div id="errorbox" class="notification is-danger is-size-7-mobile" style="display: none;">
|
||||||
|
</div>
|
||||||
|
<div class="has-text-centered">
|
||||||
|
<input id="login-button" name="login-button" type="submit" class="form-button button is-primary is-centered" value="Passwort zurücksetzen"></input>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</form>
|
||||||
|
{{end}}
|
||||||
|
{{end}}
|
||||||
@@ -0,0 +1,7 @@
|
|||||||
|
{{define "body_content"}}
|
||||||
|
{{ if ne .UserName "" }}
|
||||||
|
<p>Datenauswertung</p>
|
||||||
|
{{ else }}
|
||||||
|
<h4>Bitte zuerst <a href="login.html">einloggen</a></h4>
|
||||||
|
{{end}}
|
||||||
|
{{end}}
|
||||||
@@ -0,0 +1,5 @@
|
|||||||
|
{{define "body_content"}}
|
||||||
|
<div class="notification is-danger">
|
||||||
|
<strong>Benutzer existiert nicht!</strong>
|
||||||
|
</div>
|
||||||
|
{{end}}
|
||||||
Vendored
+1
@@ -0,0 +1 @@
|
|||||||
|
/*! bulma.io v0.7.4 | MIT License | github.com/jgthms/bulma */@-webkit-keyframes spinAround{from{-webkit-transform:rotate(0);transform:rotate(0)}to{-webkit-transform:rotate(359deg);transform:rotate(359deg)}}@keyframes spinAround{from{-webkit-transform:rotate(0);transform:rotate(0)}to{-webkit-transform:rotate(359deg);transform:rotate(359deg)}}.breadcrumb,.button,.delete,.file,.is-unselectable,.modal-close,.pagination-ellipsis,.pagination-link,.pagination-next,.pagination-previous,.tabs{-webkit-touch-callout:none;-webkit-user-select:none;-moz-user-select:none;-ms-user-select:none;user-select:none}.navbar-link:not(.is-arrowless)::after,.select:not(.is-multiple):not(.is-loading)::after{border:3px solid transparent;border-radius:2px;border-right:0;border-top:0;content:" ";display:block;height:.625em;margin-top:-.4375em;pointer-events:none;position:absolute;top:50%;-webkit-transform:rotate(-45deg);transform:rotate(-45deg);-webkit-transform-origin:center;transform-origin:center;width:.625em}.block:not(:last-child),.box:not(:last-child),.breadcrumb:not(:last-child),.content:not(:last-child),.highlight:not(:last-child),.level:not(:last-child),.list:not(:last-child),.message:not(:last-child),.notification:not(:last-child),.progress:not(:last-child),.subtitle:not(:last-child),.table-container:not(:last-child),.table:not(:last-child),.tabs:not(:last-child),.title:not(:last-child){margin-bottom:1.5rem}.delete,.modal-close{-moz-appearance:none;-webkit-appearance:none;background-color:rgba(10,10,10,.2);border:none;border-radius:290486px;cursor:pointer;pointer-events:auto;display:inline-block;flex-grow:0;flex-shrink:0;font-size:0;height:20px;max-height:20px;max-width:20px;min-height:20px;min-width:20px;outline:0;position:relative;vertical-align:top;width:20px}.delete::after,.delete::before,.modal-close::after,.modal-close::before{background-color:#fff;content:"";display:block;left:50%;position:absolute;top:50%;-webkit-transform:translateX(-50%) translateY(-50%) rotate(45deg);transform:translateX(-50%) translateY(-50%) rotate(45deg);-webkit-transform-origin:center center;transform-origin:center center}.delete::before,.modal-close::before{height:2px;width:50%}.delete::after,.modal-close::after{height:50%;width:2px}.delete:focus,.delete:hover,.modal-close:focus,.modal-close:hover{background-color:rgba(10,10,10,.3)}.delete:active,.modal-close:active{background-color:rgba(10,10,10,.4)}.is-small.delete,.is-small.modal-close{height:16px;max-height:16px;max-width:16px;min-height:16px;min-width:16px;width:16px}.is-medium.delete,.is-medium.modal-close{height:24px;max-height:24px;max-width:24px;min-height:24px;min-width:24px;width:24px}.is-large.delete,.is-large.modal-close{height:32px;max-height:32px;max-width:32px;min-height:32px;min-width:32px;width:32px}.button.is-loading::after,.control.is-loading::after,.loader,.select.is-loading::after{-webkit-animation:spinAround .5s infinite linear;animation:spinAround .5s infinite linear;border:2px solid #dbdbdb;border-radius:290486px;border-right-color:transparent;border-top-color:transparent;content:"";display:block;height:1em;position:relative;width:1em}.hero-video,.image.is-16by9 .has-ratio,.image.is-16by9 img,.image.is-1by1 .has-ratio,.image.is-1by1 img,.image.is-1by2 .has-ratio,.image.is-1by2 img,.image.is-1by3 .has-ratio,.image.is-1by3 img,.image.is-2by1 .has-ratio,.image.is-2by1 img,.image.is-2by3 .has-ratio,.image.is-2by3 img,.image.is-3by1 .has-ratio,.image.is-3by1 img,.image.is-3by2 .has-ratio,.image.is-3by2 img,.image.is-3by4 .has-ratio,.image.is-3by4 img,.image.is-3by5 .has-ratio,.image.is-3by5 img,.image.is-4by3 .has-ratio,.image.is-4by3 img,.image.is-4by5 .has-ratio,.image.is-4by5 img,.image.is-5by3 .has-ratio,.image.is-5by3 img,.image.is-5by4 .has-ratio,.image.is-5by4 img,.image.is-9by16 .has-ratio,.image.is-9by16 img,.image.is-square .has-ratio,.image.is-square img,.is-overlay,.modal,.modal-background{bottom:0;left:0;position:absolute;right:0;top:0}.button,.file-cta,.file-name,.input,.pagination-ellipsis,.pagination-link,.pagination-next,.pagination-previous,.select select,.textarea{-moz-appearance:none;-webkit-appearance:none;align-items:center;border:1px solid transparent;border-radius:4px;box-shadow:none;display:inline-flex;font-size:1rem;height:2.25em;justify-content:flex-start;line-height:1.5;padding-bottom:calc(.375em - 1px);padding-left:calc(.625em - 1px);padding-right:calc(.625em - 1px);padding-top:calc(.375em - 1px);position:relative;vertical-align:top}.button:active,.button:focus,.file-cta:active,.file-cta:focus,.file-name:active,.file-name:focus,.input:active,.input:focus,.is-active.button,.is-active.file-cta,.is-active.file-name,.is-active.input,.is-active.pagination-ellipsis,.is-active.pagination-link,.is-active.pagination-next,.is-active.pagination-previous,.is-active.textarea,.is-focused.button,.is-focused.file-cta,.is-focused.file-name,.is-focused.input,.is-focused.pagination-ellipsis,.is-focused.pagination-link,.is-focused.pagination-next,.is-focused.paginLine truncated
|
||||||
@@ -0,0 +1,29 @@
|
|||||||
|
.image.is-10by1 img, .image.is-20by3 img {
|
||||||
|
bottom: 0;
|
||||||
|
left: 0;
|
||||||
|
position: absolute;
|
||||||
|
right: 0;
|
||||||
|
top: 0;
|
||||||
|
height: 100%;
|
||||||
|
width: 100%;
|
||||||
|
}
|
||||||
|
|
||||||
|
.image.is-10by1 {
|
||||||
|
padding-top: 10%;
|
||||||
|
}
|
||||||
|
|
||||||
|
.image.is-20by3 {
|
||||||
|
padding-top: 15%;
|
||||||
|
}
|
||||||
|
|
||||||
|
hr {
|
||||||
|
margin: 0px 0 5px 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
.signup-box {
|
||||||
|
margin: auto;
|
||||||
|
width: 300px;
|
||||||
|
background: rgba(255,255,255,0.05);
|
||||||
|
border: 1px solid rgba(255,255,255,0.3);
|
||||||
|
border-radius: 10px;
|
||||||
|
}
|
||||||
Binary file not shown.
|
After Width: | Height: | Size: 5.3 KiB |
Binary file not shown.
|
After Width: | Height: | Size: 1.3 KiB |
Binary file not shown.
|
After Width: | Height: | Size: 2.8 KiB |
Binary file not shown.
|
After Width: | Height: | Size: 47 KiB |
Binary file not shown.
|
After Width: | Height: | Size: 24 KiB |
@@ -0,0 +1,5 @@
|
|||||||
|
/*!
|
||||||
|
* Font Awesome Free 5.1.0 by @fontawesome - https://fontawesome.com
|
||||||
|
* License - https://fontawesome.com/license (Icons: CC BY 4.0, Fonts: SIL OFL 1.1, Code: MIT License)
|
||||||
|
*/
|
||||||
|
!function(){"use strict";var c={};try{"undefined"!=typeof window&&(c=window)}catch(c){}var l=(c.navigator||{}).userAgent,h=void 0===l?"":l,z=c,v=(~h.indexOf("MSIE")||h.indexOf("Trident/"),"___FONT_AWESOME___"),m=function(){try{return!0}catch(c){return!1}}(),s=[1,2,3,4,5,6,7,8,9,10],e=s.concat([11,12,13,14,15,16,17,18,19,20]);["xs","sm","lg","fw","ul","li","border","pull-left","pull-right","spin","pulse","rotate-90","rotate-180","rotate-270","flip-horizontal","flip-vertical","stack","stack-1x","stack-2x","inverse","layers","layers-text","layers-counter"].concat(s.map(function(c){return c+"x"})).concat(e.map(function(c){return"w-"+c}));var a=z||{};a[v]||(a[v]={}),a[v].styles||(a[v].styles={}),a[v].hooks||(a[v].hooks={}),a[v].shims||(a[v].shims=[]);var t=a[v],M=Object.assign||function(c){for(var l=1;l<arguments.length;l++){var h=arguments[l];for(var z in h)Object.prototype.hasOwnProperty.call(h,z)&&(c[z]=h[z])}return c};var f={"500px":[448,512,[],"f26e","M103.3 344.3c-6.5-14.2-6.9-18.3 7.4-23.1 25.6-8 8 9.2 43.2 49.2h.3v-93.9c1.2-50.2 44-92.2 97.7-92.2 53.9 0 97.7 43.5 97.7 96.8 0 63.4-60.8 113.2-128.5 93.3-10.5-4.2-2.1-31.7 8.5-28.6 53 0 89.4-10.1 89.4-64.4 0-61-77.1-89.6-116.9-44.6-23.5 26.4-17.6 42.1-17.6 157.6 50.7 31 118.3 22 160.4-20.1 24.8-24.8 38.5-58 38.5-93 0-35.2-13.8-68.2-38.8-93.3-24.8-24.8-57.8-38.5-93.3-38.5s-68.8 13.8-93.5 38.5c-.3.3-16 16.5-21.2 23.9l-.5.6c-3.3 4.7-6.3 9.1-20.1 6.1-6.9-1.7-14.3-5.8-14.3-11.8V20c0-5 3.9-10.5 10.5-10.5h241.3c8.3 0 8.3 11.6 8.3 15.1 0 3.9 0 15.1-8.3 15.1H130.3v132.9h.3c104.2-109.8 282.8-36 282.8 108.9 0 178.1-244.8 220.3-310.1 62.8zm63.3-260.8c-.5 4.2 4.6 24.5 14.6 20.6C306 56.6 384 144.5 390.6 144.5c4.8 0 22.8-15.3 14.3-22.8-93.2-89-234.5-57-238.3-38.2zM393 414.7C283 524.6 94 475.5 61 310.5c0-12.2-30.4-7.4-28.9 3.3 24 173.4 246 256.9 381.6 121.3 6.9-7.8-12.6-28.4-20.7-20.4zM213.6 306.6c0 4 4.3 7.3 5.5 8.5 3 3 6.1 4.4 8.5 4.4 3.8 0 2.6.2 22.3-19.5 19.6 19.3 19.1 19.5 22.3 19.5 5.4 0 18.5-10.4 10.7-18.2L265.6 284l18.2-18.2c6.3-6.8-10.1-21.8-16.2-15.7L249.7 268c-18.6-18.8-18.4-19.5-21.5-19.5-5 0-18 11.7-12.4 17.3L234 284c-18.1 17.9-20.4 19.2-20.4 22.6z"],"accessible-icon":[448,512,[],"f368","M423.9 255.8L411 413.1c-3.3 40.7-63.9 35.1-60.6-4.9l10-122.5-41.1 2.3c10.1 20.7 15.8 43.9 15.8 68.5 0 41.2-16.1 78.7-42.3 106.5l-39.3-39.3c57.9-63.7 13.1-167.2-74-167.2-25.9 0-49.5 9.9-67.2 26L73 243.2c22-20.7 50.1-35.1 81.4-40.2l75.3-85.7-42.6-24.8-51.6 46c-30 26.8-70.6-18.5-40.5-45.4l68-60.7c9.8-8.8 24.1-10.2 35.5-3.6 0 0 139.3 80.9 139.5 81.1 16.2 10.1 20.7 36 6.1 52.6L285.7 229l106.1-5.9c18.5-1.1 33.6 14.4 32.1 32.7zm-64.9-154c28.1 0 50.9-22.8 50.9-50.9C409.9 22.8 387.1 0 359 0c-28.1 0-50.9 22.8-50.9 50.9 0 28.1 22.8 50.9 50.9 50.9zM179.6 456.5c-80.6 0-127.4-90.6-82.7-156.1l-39.7-39.7C36.4 287 24 320.3 24 356.4c0 130.7 150.7 201.4 251.4 122.5l-39.7-39.7c-16 10.9-35.3 17.3-56.1 17.3z"],accusoft:[640,512,[],"f369","M482.2 372.1C476.5 365.2 250 75 242.3 65.5c-13.7-17.2 0-16.8 19.2-16.9 9.7-.1 106.3-.6 116.5-.6 24.1-.1 28.7.6 38.4 12.8 2.1 2.7 205.1 245.8 207.2 248.3 5.5 6.7 15.2 19.1 7.2 23.4-2.4 1.3-114.6 47.7-117.8 48.9-10.1 4-17.5 6.8-30.8-9.3m114.7-5.6s-115 50.4-117.5 51.6c-16 7.3-26.9-3.2-36.7-14.6l-57.1-74c-5.4-.9-60.4-9.6-65.3-9.3-3.1.2-9.6.8-14.4 2.9-4.9 2.1-145.2 52.8-150.2 54.7-5.1 2-11.4 3.6-11.1 7.6.2 2.5 2 2.6 4.6 3.5 2.7.8 300.9 67.6 308 69.1 15.6 3.3 38.5 10.5 53.6 1.7 2.1-1.2 123.8-76.4 125.8-77.8 5.4-4 4.3-6.8-1.7-8.2-2.3-.3-24.6-4.7-38-7.2m-326-181.3s-12 1.6-25 15.1c-9 9.3-242.1 239.1-243.4 240.9-7 10 1.6 6.8 15.7 1.7.8 0 114.5-36.6 114.5-36.6.5-.6-.1-.1.6-.6-.4-5.1-.8-26.2-1-27.7-.6-5.2 2.2-6.9 7-8.9l92.6-33.8c.6-.8 88.5-81.7 90.2-83.3v-1l-51.2-65.8"],adn:[496,512,[],"f170","M248 167.5l64.9 98.8H183.1l64.9-98.8zM496 256c0 136.9-111.1 248-248 248S0 392.9 0 256 111.1 8 248 8s248 111.1 248 248zm-99.8 82.7L248 115.5 99.8 338.7h30.4l33.6-51.7h168.6l33.6 51.7h30.2z"],adversal:[512,512,[],"f36a","M482.1 32H28.7C5.8 32 0 37.9 0 60.9v390.2C0 474.4 5.8 480 28.7 480h453.4c24.4 0 29.9-5.2 29.9-29.7V62.2c0-24.6-5.4-30.2-29.9-30.2zM178.4 220.3c-27.5-20.2-72.1-8.7-84.2 23.4-4.3 11.1-9.3 9.5-17.5 8.3-9.7-1.5-17.2-3.2-22.5-5.5-28.8-11.4 8.6-55.3 24.9-64.3 41.1-21.4 83.4-22.2 125.3-4.8 40.9 16.8 34.5 59.2 34.5 128.5 2.7 25.8-4.3 58.3 9.3 88.8 1.9 4.4.4 7.9-2.7 10.7-8.4 6.7-39.3 2.2-46.6-7.4-1.9-2.2-1.8-3.6-3.9-6.2-3.6-3.9-7.3-2.2-11.9 1-57.4 36.4-140.3 21.4-147-43.3-3.1-29.3 12.4-57.1 39.6-71 38.2-19.5 112.2-11.8 114-30.9 1.1-10.2-1.9-20.1-11.3-27.3zm286.7 222c0 15.1-11.1 9.9-17.8 9.9H52.4c-7.4 0-18.2 4.8-17.8-10.7.4-13.9 10.5-9.1 17.1-9.1 132.3-.4 264.5-.4 396.8 0 6.8 0 16.6-4.4 16.6 9.9zm3.8-340.5v291c0 5.7-.7 13.9-8.1 13.9-12.4-.4-27.5 7.1-36.1-5.6-5.8-8.7-7.8-4-12.4-1.2-53.4 29.7-128.1 7.1-144.4-85.2-6.1-33.4-.7-67.1 15.7-100 11.8-23.9 56.9-76.1 136.1-30.5v-71c0-26.2-.1-26.2 26-26.2 3.1 0 6.6.4 9.7 0 10.1-.8 13.6 4.4 13.6 14.3-.1.2-.1.3-.1.5zm-51.5 232.3c-19.5 47.6-72.9 43.3-90 5.2-15.1-33.3-15.5-68.2.4-101.5 16.3-34.1 59.7-35.7 81.5-4.8 20.6 28.8 14.9 84.6 8.1 101.1zm-2Line truncated
|
||||||
Vendored
+2
@@ -0,0 +1,2 @@
|
|||||||
|
/*! jQuery v3.3.1 | (c) JS Foundation and other contributors | jquery.org/license */
|
||||||
|
!function(e,t){"use strict";"object"==typeof module&&"object"==typeof module.exports?module.exports=e.document?t(e,!0):function(e){if(!e.document)throw new Error("jQuery requires a window with a document");return t(e)}:t(e)}("undefined"!=typeof window?window:this,function(e,t){"use strict";var n=[],r=e.document,i=Object.getPrototypeOf,o=n.slice,a=n.concat,s=n.push,u=n.indexOf,l={},c=l.toString,f=l.hasOwnProperty,p=f.toString,d=p.call(Object),h={},g=function e(t){return"function"==typeof t&&"number"!=typeof t.nodeType},y=function e(t){return null!=t&&t===t.window},v={type:!0,src:!0,noModule:!0};function m(e,t,n){var i,o=(t=t||r).createElement("script");if(o.text=e,n)for(i in v)n[i]&&(o[i]=n[i]);t.head.appendChild(o).parentNode.removeChild(o)}function x(e){return null==e?e+"":"object"==typeof e||"function"==typeof e?l[c.call(e)]||"object":typeof e}var b="3.3.1",w=function(e,t){return new w.fn.init(e,t)},T=/^[\s\uFEFF\xA0]+|[\s\uFEFF\xA0]+$/g;w.fn=w.prototype={jquery:"3.3.1",constructor:w,length:0,toArray:function(){return o.call(this)},get:function(e){return null==e?o.call(this):e<0?this[e+this.length]:this[e]},pushStack:function(e){var t=w.merge(this.constructor(),e);return t.prevObject=this,t},each:function(e){return w.each(this,e)},map:function(e){return this.pushStack(w.map(this,function(t,n){return e.call(t,n,t)}))},slice:function(){return this.pushStack(o.apply(this,arguments))},first:function(){return this.eq(0)},last:function(){return this.eq(-1)},eq:function(e){var t=this.length,n=+e+(e<0?t:0);return this.pushStack(n>=0&&n<t?[this[n]]:[])},end:function(){return this.prevObject||this.constructor()},push:s,sort:n.sort,splice:n.splice},w.extend=w.fn.extend=function(){var e,t,n,r,i,o,a=arguments[0]||{},s=1,u=arguments.length,l=!1;for("boolean"==typeof a&&(l=a,a=arguments[s]||{},s++),"object"==typeof a||g(a)||(a={}),s===u&&(a=this,s--);s<u;s++)if(null!=(e=arguments[s]))for(t in e)n=a[t],a!==(r=e[t])&&(l&&r&&(w.isPlainObject(r)||(i=Array.isArray(r)))?(i?(i=!1,o=n&&Array.isArray(n)?n:[]):o=n&&w.isPlainObject(n)?n:{},a[t]=w.extend(l,o,r)):void 0!==r&&(a[t]=r));return a},w.extend({expando:"jQuery"+("3.3.1"+Math.random()).replace(/\D/g,""),isReady:!0,error:function(e){throw new Error(e)},noop:function(){},isPlainObject:function(e){var t,n;return!(!e||"[object Object]"!==c.call(e))&&(!(t=i(e))||"function"==typeof(n=f.call(t,"constructor")&&t.constructor)&&p.call(n)===d)},isEmptyObject:function(e){var t;for(t in e)return!1;return!0},globalEval:function(e){m(e)},each:function(e,t){var n,r=0;if(C(e)){for(n=e.length;r<n;r++)if(!1===t.call(e[r],r,e[r]))break}else for(r in e)if(!1===t.call(e[r],r,e[r]))break;return e},trim:function(e){return null==e?"":(e+"").replace(T,"")},makeArray:function(e,t){var n=t||[];return null!=e&&(C(Object(e))?w.merge(n,"string"==typeof e?[e]:e):s.call(n,e)),n},inArray:function(e,t,n){return null==t?-1:u.call(t,e,n)},merge:function(e,t){for(var n=+t.length,r=0,i=e.length;r<n;r++)e[i++]=t[r];return e.length=i,e},grep:function(e,t,n){for(var r,i=[],o=0,a=e.length,s=!n;o<a;o++)(r=!t(e[o],o))!==s&&i.push(e[o]);return i},map:function(e,t,n){var r,i,o=0,s=[];if(C(e))for(r=e.length;o<r;o++)null!=(i=t(e[o],o,n))&&s.push(i);else for(o in e)null!=(i=t(e[o],o,n))&&s.push(i);return a.apply([],s)},guid:1,support:h}),"function"==typeof Symbol&&(w.fn[Symbol.iterator]=n[Symbol.iterator]),w.each("Boolean Number String Function Array Date RegExp Object Error Symbol".split(" "),function(e,t){l["[object "+t+"]"]=t.toLowerCase()});function C(e){var t=!!e&&"length"in e&&e.length,n=x(e);return!g(e)&&!y(e)&&("array"===n||0===t||"number"==typeof t&&t>0&&t-1 in e)}var E=function(e){var t,n,r,i,o,a,s,u,l,c,f,p,d,h,g,y,v,m,x,b="sizzle"+1*new Date,w=e.document,T=0,C=0,E=ae(),k=ae(),S=ae(),D=function(e,t){return e===t&&(f=!0),0},N={}.hasOwnProperty,A=[],j=A.pop,q=A.push,L=A.push,H=A.slice,O=function(e,t){for(var n=0,r=e.length;n<r;n++)if(e[n]===t)return n;return-1},P="checked|selected|async|autofocus|autoplay|controls|defer|disabled|hidden|ismap|loop|multiple|open|readonly|required|scoped",M="[\\x20\\t\\r\\n\\f]",R="(?:\\\\.|[\\w-]|[^\0-\\xa0])+",I="\\["+M+"*("+R+")(?:"+M+"*([*^$|!~]?=)"+M+"*(?:'((?:\\\\.|[^\\\\'])*)'|\"((?:\\\\.|[^\\\\\"])*)\"|("+R+"))|)"+M+"*\\]",W=":("+R+")(?:\\((('((?:\\\\.|[^\\\\'])*)'|\"((?:\\\\.|[^\\\\\"])*)\")|((?:\\\\.|[^\\\\()[\\]]|"+I+")*)|.*)\\)|)",$=new RegExp(M+"+","g"),B=new RegExp("^"+M+"+|((?:^|[^\\\\])(?:\\\\.)*)"+M+"+$","g"),F=new RegExp("^"+M+"*,"+M+"*"),_=new RegExp("^"+M+"*([>+~]|"+M+")"+M+"*"),z=new RegExp("="+M+"*([^\\]'\"]*?)"+M+"*\\]","g"),X=new RegExp(W),U=new RegExp("^"+R+"$"),V={ID:new RegExp("^#("+R+")"),CLASS:new RegExp("^\\.("+R+")"),TAG:new RegExp("^("+R+"|[*])"),ATTR:new RegExp("^"+I),PSEUDO:new RegExp("^"+W),CHILD:new RegExp("^:(only|first|last|nth|nth-last)-(child|of-type)(?:\\("+M+"*(even|odd|(([+-]|)(\\d*)n|)"+M+"*(?:([+-]|)"+M+"*(\\d+)|))"+M+"*\\)|)","i"),bool:new RegExp("^(?:"+P+")$","i"),needsContext:new RegExp("^"+M+"*[>+~]|:(even|odd|eq|gt|lt|nth|first|last)Line truncated
|
||||||
@@ -0,0 +1,70 @@
|
|||||||
|
$(document).ready(function() {
|
||||||
|
|
||||||
|
$("#email").focus();
|
||||||
|
|
||||||
|
// Check for click events on the navbar burger icon
|
||||||
|
$(".navbar-burger").click(function() {
|
||||||
|
// Toggle the "is-active" class on both the "navbar-burger" and the "navbar-menu"
|
||||||
|
$(".navbar-burger").toggleClass("is-active");
|
||||||
|
$(".navbar-menu").toggleClass("is-active");
|
||||||
|
|
||||||
|
});
|
||||||
|
|
||||||
|
// Login Button
|
||||||
|
$("#login-button").click(function(e){
|
||||||
|
//alert(true);
|
||||||
|
$("#login-form").submit();
|
||||||
|
});
|
||||||
|
|
||||||
|
// Login Form
|
||||||
|
$("#login-form-blabla").submit(function(e){
|
||||||
|
e.preventDefault();
|
||||||
|
var formData = {
|
||||||
|
next: $("#email").val(),
|
||||||
|
email: $("#email").val(),
|
||||||
|
password: $("#password").val(),
|
||||||
|
csrf_token: $("#csrf_token").val(),
|
||||||
|
next: $("#next").val()
|
||||||
|
};
|
||||||
|
|
||||||
|
//console.log(formData);
|
||||||
|
// send ajax
|
||||||
|
$.ajax({
|
||||||
|
url: '/login', // url where to submit the request
|
||||||
|
type : "POST", // type of action POST || GET
|
||||||
|
dataType : 'json', // data type
|
||||||
|
contentType: 'application/json',
|
||||||
|
data : JSON.stringify(formData), // post data || get data
|
||||||
|
success : function(result) {
|
||||||
|
// you can see the result from the console
|
||||||
|
// tab of the developer tools
|
||||||
|
console.log('SUCCESS');
|
||||||
|
console.log(result);
|
||||||
|
window.location.replace("/");
|
||||||
|
},
|
||||||
|
error: function(result) {
|
||||||
|
//console.log(xhr, resp, text);
|
||||||
|
console.log('ERROR');
|
||||||
|
console.log(result);
|
||||||
|
var errortext = '<ul style="list-style-type:disc">';
|
||||||
|
a = result.responseJSON.response.errors.email;
|
||||||
|
if (a != undefined) {
|
||||||
|
for (i=0; i < a.length; ++i) {
|
||||||
|
errortext = errortext + "<li>" + a[i] + "</li>";
|
||||||
|
}
|
||||||
|
}
|
||||||
|
a = result.responseJSON.response.errors.password;
|
||||||
|
if (a != undefined) {
|
||||||
|
for (i=0; i < a.length; ++i) {
|
||||||
|
errortext = errortext + "<li>" + a[i] + "</li>";
|
||||||
|
}
|
||||||
|
}
|
||||||
|
errortext = errortext + "</ul>";
|
||||||
|
$('#errorbox').html(errortext);
|
||||||
|
$('#errorbox').show();
|
||||||
|
}
|
||||||
|
})
|
||||||
|
});
|
||||||
|
|
||||||
|
|
||||||
|
});
|
||||||
@@ -0,0 +1,15 @@
|
|||||||
|
[Unit]
|
||||||
|
Description=mini-beieli web service
|
||||||
|
After=syslog.target
|
||||||
|
After=network.target
|
||||||
|
|
||||||
|
[Service]
|
||||||
|
Type=simple
|
||||||
|
User=beieli
|
||||||
|
Group=beieli
|
||||||
|
WorkingDirectory=/home/beieli/mini-beieli-web
|
||||||
|
ExecStart=/home/beieli/mini-beieli-web/mini-beieli-web
|
||||||
|
Restart=always
|
||||||
|
|
||||||
|
[Install]
|
||||||
|
WantedBy=multi-user.target
|
||||||
@@ -0,0 +1,88 @@
|
|||||||
|
{{define "header_additions"}}{{end}}
|
||||||
|
{{define "layout"}}<!DOCTYPE html>
|
||||||
|
<html>
|
||||||
|
<head>
|
||||||
|
<meta charset="utf-8">
|
||||||
|
<meta name="viewport" content="width=device-width, initial-scale=1">
|
||||||
|
<title>mini-beieli.ch - die besondere Bienenstockwaage</title>
|
||||||
|
<link rel="stylesheet" href="/static/css/bulma-0.7.4/bulma.min.css">
|
||||||
|
<link rel="stylesheet" href="static/css/mini-beieli-web.css">
|
||||||
|
|
||||||
|
<script defer src="/static/js/fontawesome-5.1.0/all.js"></script>
|
||||||
|
<script src="/static/js/jquery-3.3.1/jquery.min.js"></script>
|
||||||
|
{{template "header_additions" . }}
|
||||||
|
</head>
|
||||||
|
<body>
|
||||||
|
<section class="section">
|
||||||
|
<div class="container">
|
||||||
|
<figure class="image is-hidden-mobile is-20by3">
|
||||||
|
<img src="/static/images/bees-banner-1000x150.jpg" alt="mini-beieli Banner" >
|
||||||
|
</figure>
|
||||||
|
<figure class="image is-hidden-tablet is-3by1">
|
||||||
|
<img src="/static/images/bees-banner-450x150.jpg" alt="mini-beieli Banner" >
|
||||||
|
</figure>
|
||||||
|
<nav class="navbar" role="navigation" aria-label="main navigation">
|
||||||
|
<div class="navbar-brand">
|
||||||
|
<a class="navbar-item" href="/">
|
||||||
|
<img src="/static/images/bee-logo-28.png" alt="mini-beieli Logo" width="28" height="28">
|
||||||
|
</a>
|
||||||
|
<a role="button" class="navbar-burger" data-target="navMenu" aria-label="menu" aria-expanded="false">
|
||||||
|
<span aria-hidden="true"></span>
|
||||||
|
<span aria-hidden="true"></span>
|
||||||
|
<span aria-hidden="true"></span>
|
||||||
|
</a>
|
||||||
|
</div>
|
||||||
|
<div class="navbar-menu" id="navMenu">
|
||||||
|
<div class="navbar-start">
|
||||||
|
<a class="navbar-item" href="/">
|
||||||
|
<div style="position:relative">
|
||||||
|
<span class="icon"><i class="fa fa-home"></i></span>
|
||||||
|
<span>Home</span>
|
||||||
|
</div>
|
||||||
|
</a>
|
||||||
|
<a class="navbar-item" href="/contact.html">
|
||||||
|
<div style="position:relative">
|
||||||
|
<span class="icon"><i class="fa fa-address-card"></i></span>
|
||||||
|
<span>Kontakt</span>
|
||||||
|
</div>
|
||||||
|
</a>
|
||||||
|
{{ if ne .UserName "" }}
|
||||||
|
<a class="navbar-item" href="/scales.html">
|
||||||
|
<div style="position:relative">
|
||||||
|
<span class="icon"><i class="fa fa-balance-scale"></i></span>
|
||||||
|
<span>Meine Waagen</span>
|
||||||
|
</div>
|
||||||
|
</a>
|
||||||
|
{{ end }}
|
||||||
|
</div>
|
||||||
|
<div class="navbar-end">
|
||||||
|
{{ if ne .UserName "" }}
|
||||||
|
<a class="navbar-item" href="/logout">
|
||||||
|
<div style="position:relative">
|
||||||
|
<span class="icon"><i class="fa fa-sign-out-alt"></i></span>
|
||||||
|
<span>Logout {{ .UserName }}</span>
|
||||||
|
</div>
|
||||||
|
</a>
|
||||||
|
{{ else }}
|
||||||
|
<a class="navbar-item" href="/login.html">
|
||||||
|
<div style="position:relative">
|
||||||
|
<span class="icon"><i class="fa fa-sign-in-alt"></i></span>
|
||||||
|
<span>Login</span>
|
||||||
|
</div>
|
||||||
|
</a>
|
||||||
|
{{ end }}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</nav>
|
||||||
|
<hr />
|
||||||
|
{{template "body_content" . }}
|
||||||
|
</div>
|
||||||
|
</section>
|
||||||
|
<script src="/static/js/mini-beieli-web.js"></script>
|
||||||
|
</body>
|
||||||
|
</html>
|
||||||
|
{{end}}
|
||||||
Reference in new issue
Block a user