Compare commits
46 Commits
b2a701c87a
...
v0.12.0
Author | SHA1 | Date | |
---|---|---|---|
b36e0ea503 | |||
863581f590 | |||
aec829ad85 | |||
298ea458ca | |||
533053aef0 | |||
c00645432b | |||
91d53a0f2a | |||
b3f31f398d | |||
cf4d4f151a | |||
202d04f323 | |||
bc4d8fa37e | |||
d2b21e7405 | |||
e3c192359f | |||
46532e4c85 | |||
c722135a56 | |||
887fa863bc | |||
74d71cfb6a | |||
ca7e7cddd3 | |||
94431a2aa9 | |||
5b1f20c5bc | |||
d0c566f8df | |||
5e586aa49a | |||
66b2743d3d | |||
3723b2b5e6 | |||
ce788bfd50 | |||
230a6278cc | |||
42d6e0c198 | |||
e1af2979af | |||
f6dedc6f10 | |||
cdf0a49550 | |||
c3c0650210 | |||
d077f700d8 | |||
ec752b1c66 | |||
46aef4f12f | |||
1b29e328cf | |||
e50cb819f3 | |||
c32e38ca10 | |||
d7c8c7a43a | |||
1cd3edc90c | |||
0e768c9f61 | |||
1fcd775cc5 | |||
203a1ed147 | |||
ef1914ee5c | |||
084b101e31 | |||
b2db128aa9 | |||
081e880fb6 |
@ -2,6 +2,7 @@ package backend
|
|||||||
|
|
||||||
import (
|
import (
|
||||||
"fmt"
|
"fmt"
|
||||||
|
"image"
|
||||||
"io"
|
"io"
|
||||||
"os"
|
"os"
|
||||||
|
|
||||||
@ -10,9 +11,14 @@ import (
|
|||||||
"github.com/google/uuid"
|
"github.com/google/uuid"
|
||||||
)
|
)
|
||||||
|
|
||||||
|
var ErrUnsupportedFormat error = image.ErrFormat // used internally by imaging
|
||||||
|
|
||||||
func SaveImage(c *Config, src io.Reader) (string, error) {
|
func SaveImage(c *Config, src io.Reader) (string, error) {
|
||||||
img, err := imaging.Decode(src, imaging.AutoOrientation(true))
|
img, err := imaging.Decode(src, imaging.AutoOrientation(true))
|
||||||
if err != nil {
|
if err != nil {
|
||||||
|
if err == ErrUnsupportedFormat {
|
||||||
|
return "", ErrUnsupportedFormat
|
||||||
|
}
|
||||||
return "", fmt.Errorf("error decoding image: %v", err)
|
return "", fmt.Errorf("error decoding image: %v", err)
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -23,8 +29,8 @@ func SaveImage(c *Config, src io.Reader) (string, error) {
|
|||||||
img = imaging.Resize(img, c.MaxImgWidth, 0, imaging.Lanczos)
|
img = imaging.Resize(img, c.MaxImgWidth, 0, imaging.Lanczos)
|
||||||
}
|
}
|
||||||
|
|
||||||
filename := fmt.Sprint(c.PicsDir, "/", uuid.New(), ".webp")
|
filename := fmt.Sprint(uuid.New(), ".webp")
|
||||||
file, err := os.Create(filename)
|
file, err := os.Create(c.PicsDir + "/" + filename)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return "", fmt.Errorf("error creating new image file: %v", err)
|
return "", fmt.Errorf("error creating new image file: %v", err)
|
||||||
}
|
}
|
||||||
|
@ -47,7 +47,7 @@ func (db *DB) AddUser(u *User, pass string) (int64, error) {
|
|||||||
return id, nil
|
return id, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
func (db *DB) GetID(userName string) (int64, bool) {
|
func (db *DB) GetID(userName string) int64 {
|
||||||
var id int64
|
var id int64
|
||||||
|
|
||||||
query := `
|
query := `
|
||||||
@ -56,11 +56,11 @@ func (db *DB) GetID(userName string) (int64, bool) {
|
|||||||
WHERE username = ?
|
WHERE username = ?
|
||||||
`
|
`
|
||||||
row := db.QueryRow(query, userName)
|
row := db.QueryRow(query, userName)
|
||||||
if err := row.Scan(&id); err != nil {
|
if err := row.Scan(&id); err != nil { // seems like the only possible error is ErrNoRows
|
||||||
return 0, false
|
return 0
|
||||||
}
|
}
|
||||||
|
|
||||||
return id, true
|
return id
|
||||||
}
|
}
|
||||||
|
|
||||||
func (db *DB) CheckPassword(id int64, pass string) error {
|
func (db *DB) CheckPassword(id int64, pass string) error {
|
||||||
@ -146,7 +146,7 @@ func (db *DB) GetUser(id int64) (*User, error) {
|
|||||||
return user, nil
|
return user, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
func (db *DB) UpdateOwnAttributes(id int64, user, first, last, oldPass, newPass, newPass2 string) error {
|
func (db *DB) UpdateOwnUserAttributes(id int64, user, first, last, oldPass, newPass, newPass2 string) error {
|
||||||
passwordEmpty := true
|
passwordEmpty := true
|
||||||
if len(newPass) > 0 || len(newPass2) > 0 {
|
if len(newPass) > 0 || len(newPass2) > 0 {
|
||||||
if newPass != newPass2 {
|
if newPass != newPass2 {
|
||||||
@ -228,7 +228,7 @@ func (db *DB) AddFirstUser(u *User, pass string) (int64, error) {
|
|||||||
if err = tx.Commit(); err != nil {
|
if err = tx.Commit(); err != nil {
|
||||||
return 0, fmt.Errorf("error committing transaction: %v", err)
|
return 0, fmt.Errorf("error committing transaction: %v", err)
|
||||||
}
|
}
|
||||||
return 2, nil
|
return -1, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
hashedPass, err := bcrypt.GenerateFromPassword([]byte(pass), bcrypt.DefaultCost)
|
hashedPass, err := bcrypt.GenerateFromPassword([]byte(pass), bcrypt.DefaultCost)
|
||||||
|
@ -33,13 +33,14 @@ func WriteArticle(c *b.Config, db *b.DB, s *b.CookieStore) http.HandlerFunc {
|
|||||||
return func(w http.ResponseWriter, r *http.Request) {
|
return func(w http.ResponseWriter, r *http.Request) {
|
||||||
session, err := getSession(w, r, c, s)
|
session, err := getSession(w, r, c, s)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
|
log.Println(err)
|
||||||
|
http.Error(w, err.Error(), http.StatusInternalServerError)
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
data := &EditorHTMLData{Action: "submit"}
|
var data *EditorHTMLData
|
||||||
|
|
||||||
if session.Values["article"] == nil {
|
if session.Values["article"] == nil {
|
||||||
data = &EditorHTMLData{Article: new(b.Article)}
|
data = &EditorHTMLData{Action: "submit", Article: new(b.Article)}
|
||||||
} else {
|
} else {
|
||||||
data = session.Values["article"].(*EditorHTMLData)
|
data = session.Values["article"].(*EditorHTMLData)
|
||||||
}
|
}
|
||||||
@ -52,7 +53,11 @@ func WriteArticle(c *b.Config, db *b.DB, s *b.CookieStore) http.HandlerFunc {
|
|||||||
}
|
}
|
||||||
|
|
||||||
tmpl, err := template.ParseFiles(c.WebDir + "/templates/editor.html")
|
tmpl, err := template.ParseFiles(c.WebDir + "/templates/editor.html")
|
||||||
template.Must(tmpl, err).ExecuteTemplate(w, "page-content", data)
|
if err = template.Must(tmpl, err).ExecuteTemplate(w, "page-content", data); err != nil {
|
||||||
|
log.Println(err)
|
||||||
|
http.Error(w, err.Error(), http.StatusInternalServerError)
|
||||||
|
return
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -60,6 +65,8 @@ func SubmitArticle(c *b.Config, db *b.DB, s *b.CookieStore) http.HandlerFunc {
|
|||||||
return func(w http.ResponseWriter, r *http.Request) {
|
return func(w http.ResponseWriter, r *http.Request) {
|
||||||
session, err := getSession(w, r, c, s)
|
session, err := getSession(w, r, c, s)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
|
log.Println(err)
|
||||||
|
http.Error(w, err.Error(), http.StatusInternalServerError)
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -80,6 +87,15 @@ func SubmitArticle(c *b.Config, db *b.DB, s *b.CookieStore) http.HandlerFunc {
|
|||||||
AutoGenerated: false,
|
AutoGenerated: false,
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if len(article.Title) == 0 {
|
||||||
|
http.Error(w, "Bitte den Titel eingeben.", http.StatusBadRequest)
|
||||||
|
return
|
||||||
|
}
|
||||||
|
if len(article.Description) == 0 {
|
||||||
|
http.Error(w, "Bitte die Beschreibung eingeben.", http.StatusBadRequest)
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
article.ID, err = db.AddArticle(article)
|
article.ID, err = db.AddArticle(article)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
log.Println(err)
|
log.Println(err)
|
||||||
@ -87,8 +103,14 @@ func SubmitArticle(c *b.Config, db *b.DB, s *b.CookieStore) http.HandlerFunc {
|
|||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
|
content := []byte(r.PostFormValue("article-content"))
|
||||||
|
if len(content) == 0 {
|
||||||
|
http.Error(w, "Bitte den Artikel eingeben.", http.StatusBadRequest)
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
articleAbsName := fmt.Sprint(c.ArticleDir, "/", article.ID, ".md")
|
articleAbsName := fmt.Sprint(c.ArticleDir, "/", article.ID, ".md")
|
||||||
if err = os.WriteFile(articleAbsName, []byte(r.PostFormValue("article-content")), 0644); err != nil {
|
if err = os.WriteFile(articleAbsName, content, 0644); err != nil {
|
||||||
log.Println(err)
|
log.Println(err)
|
||||||
http.Error(w, err.Error(), http.StatusInternalServerError)
|
http.Error(w, err.Error(), http.StatusInternalServerError)
|
||||||
return
|
return
|
||||||
@ -120,7 +142,11 @@ func SubmitArticle(c *b.Config, db *b.DB, s *b.CookieStore) http.HandlerFunc {
|
|||||||
|
|
||||||
tmpl, err := template.ParseFiles(c.WebDir + "/templates/hub.html")
|
tmpl, err := template.ParseFiles(c.WebDir + "/templates/hub.html")
|
||||||
tmpl = template.Must(tmpl, err)
|
tmpl = template.Must(tmpl, err)
|
||||||
tmpl.ExecuteTemplate(w, "page-content", session.Values["role"])
|
if err = tmpl.ExecuteTemplate(w, "page-content", session.Values["role"]); err != nil {
|
||||||
|
log.Println(err)
|
||||||
|
http.Error(w, err.Error(), http.StatusInternalServerError)
|
||||||
|
return
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -128,6 +154,8 @@ func ResubmitArticle(c *b.Config, db *b.DB, s *b.CookieStore) http.HandlerFunc {
|
|||||||
return func(w http.ResponseWriter, r *http.Request) {
|
return func(w http.ResponseWriter, r *http.Request) {
|
||||||
session, err := getSession(w, r, c, s)
|
session, err := getSession(w, r, c, s)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
|
log.Println(err)
|
||||||
|
http.Error(w, err.Error(), http.StatusInternalServerError)
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -139,8 +167,22 @@ func ResubmitArticle(c *b.Config, db *b.DB, s *b.CookieStore) http.HandlerFunc {
|
|||||||
}
|
}
|
||||||
|
|
||||||
title := r.PostFormValue("article-title")
|
title := r.PostFormValue("article-title")
|
||||||
|
if len(title) == 0 {
|
||||||
|
http.Error(w, "Bitte den Titel eingeben.", http.StatusBadRequest)
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
description := r.PostFormValue("article-description")
|
description := r.PostFormValue("article-description")
|
||||||
|
if len(description) == 0 {
|
||||||
|
http.Error(w, "Bitte die Beschreibung eingeben.", http.StatusBadRequest)
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
content := r.PostFormValue("article-content")
|
content := r.PostFormValue("article-content")
|
||||||
|
if len(content) == 0 {
|
||||||
|
http.Error(w, "Bitte den Artikel eingeben.", http.StatusBadRequest)
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
link := fmt.Sprint(c.ArticleDir, "/", id, ".md")
|
link := fmt.Sprint(c.ArticleDir, "/", id, ".md")
|
||||||
if err = os.WriteFile(link, []byte(content), 0644); err != nil {
|
if err = os.WriteFile(link, []byte(content), 0644); err != nil {
|
||||||
@ -179,13 +221,19 @@ func ResubmitArticle(c *b.Config, db *b.DB, s *b.CookieStore) http.HandlerFunc {
|
|||||||
|
|
||||||
tmpl, err := template.ParseFiles(c.WebDir + "/templates/hub.html")
|
tmpl, err := template.ParseFiles(c.WebDir + "/templates/hub.html")
|
||||||
tmpl = template.Must(tmpl, err)
|
tmpl = template.Must(tmpl, err)
|
||||||
tmpl.ExecuteTemplate(w, "page-content", session.Values["role"])
|
if err = tmpl.ExecuteTemplate(w, "page-content", session.Values["role"]); err != nil {
|
||||||
|
log.Println(err)
|
||||||
|
http.Error(w, err.Error(), http.StatusInternalServerError)
|
||||||
|
return
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
func ShowUnpublishedUnrejectedAndPublishedRejectedArticles(c *b.Config, db *b.DB, s *b.CookieStore) http.HandlerFunc {
|
func ShowUnpublishedUnrejectedAndPublishedRejectedArticles(c *b.Config, db *b.DB, s *b.CookieStore) http.HandlerFunc {
|
||||||
return func(w http.ResponseWriter, r *http.Request) {
|
return func(w http.ResponseWriter, r *http.Request) {
|
||||||
if _, err := getSession(w, r, c, s); err != nil {
|
if _, err := getSession(w, r, c, s); err != nil {
|
||||||
|
log.Println(err)
|
||||||
|
http.Error(w, err.Error(), http.StatusInternalServerError)
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -217,7 +265,11 @@ func ShowUnpublishedUnrejectedAndPublishedRejectedArticles(c *b.Config, db *b.DB
|
|||||||
}
|
}
|
||||||
|
|
||||||
tmpl, err := template.ParseFiles(c.WebDir + "/templates/unpublished-articles.html")
|
tmpl, err := template.ParseFiles(c.WebDir + "/templates/unpublished-articles.html")
|
||||||
template.Must(tmpl, err).ExecuteTemplate(w, "page-content", articles)
|
if err = template.Must(tmpl, err).ExecuteTemplate(w, "page-content", articles); err != nil {
|
||||||
|
log.Println(err)
|
||||||
|
http.Error(w, err.Error(), http.StatusInternalServerError)
|
||||||
|
return
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -225,6 +277,8 @@ func ShowRejectedArticles(c *b.Config, db *b.DB, s *b.CookieStore) http.HandlerF
|
|||||||
return func(w http.ResponseWriter, r *http.Request) {
|
return func(w http.ResponseWriter, r *http.Request) {
|
||||||
session, err := getSession(w, r, c, s)
|
session, err := getSession(w, r, c, s)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
|
log.Println(err)
|
||||||
|
http.Error(w, err.Error(), http.StatusInternalServerError)
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -249,13 +303,19 @@ func ShowRejectedArticles(c *b.Config, db *b.DB, s *b.CookieStore) http.HandlerF
|
|||||||
|
|
||||||
tmpl, err := template.ParseFiles(c.WebDir + "/templates/rejected-articles.html")
|
tmpl, err := template.ParseFiles(c.WebDir + "/templates/rejected-articles.html")
|
||||||
tmpl = template.Must(tmpl, err)
|
tmpl = template.Must(tmpl, err)
|
||||||
tmpl.ExecuteTemplate(w, "page-content", data)
|
if err = tmpl.ExecuteTemplate(w, "page-content", data); err != nil {
|
||||||
|
log.Println(err)
|
||||||
|
http.Error(w, err.Error(), http.StatusInternalServerError)
|
||||||
|
return
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
func ReviewRejectedArticle(c *b.Config, db *b.DB, s *b.CookieStore) http.HandlerFunc {
|
func ReviewRejectedArticle(c *b.Config, db *b.DB, s *b.CookieStore) http.HandlerFunc {
|
||||||
return func(w http.ResponseWriter, r *http.Request) {
|
return func(w http.ResponseWriter, r *http.Request) {
|
||||||
if _, err := getSession(w, r, c, s); err != nil {
|
if _, err := getSession(w, r, c, s); err != nil {
|
||||||
|
log.Println(err)
|
||||||
|
http.Error(w, err.Error(), http.StatusInternalServerError)
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -305,7 +365,11 @@ func ReviewRejectedArticle(c *b.Config, db *b.DB, s *b.CookieStore) http.Handler
|
|||||||
|
|
||||||
tmpl, err := template.ParseFiles(c.WebDir + "/templates/editor.html")
|
tmpl, err := template.ParseFiles(c.WebDir + "/templates/editor.html")
|
||||||
tmpl = template.Must(tmpl, err)
|
tmpl = template.Must(tmpl, err)
|
||||||
tmpl.ExecuteTemplate(w, "page-content", data)
|
if err = tmpl.ExecuteTemplate(w, "page-content", data); err != nil {
|
||||||
|
log.Println(err)
|
||||||
|
http.Error(w, err.Error(), http.StatusInternalServerError)
|
||||||
|
return
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -313,6 +377,8 @@ func PublishArticle(c *b.Config, db *b.DB, s *b.CookieStore) http.HandlerFunc {
|
|||||||
return func(w http.ResponseWriter, r *http.Request) {
|
return func(w http.ResponseWriter, r *http.Request) {
|
||||||
session, err := getSession(w, r, c, s)
|
session, err := getSession(w, r, c, s)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
|
log.Println(err)
|
||||||
|
http.Error(w, err.Error(), http.StatusInternalServerError)
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -390,7 +456,11 @@ func PublishArticle(c *b.Config, db *b.DB, s *b.CookieStore) http.HandlerFunc {
|
|||||||
|
|
||||||
tmpl, err := template.ParseFiles(c.WebDir + "/templates/hub.html")
|
tmpl, err := template.ParseFiles(c.WebDir + "/templates/hub.html")
|
||||||
tmpl = template.Must(tmpl, err)
|
tmpl = template.Must(tmpl, err)
|
||||||
tmpl.ExecuteTemplate(w, "page-content", session.Values["role"])
|
if err = tmpl.ExecuteTemplate(w, "page-content", session.Values["role"]); err != nil {
|
||||||
|
log.Println(err)
|
||||||
|
http.Error(w, err.Error(), http.StatusInternalServerError)
|
||||||
|
return
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -398,6 +468,8 @@ func RejectArticle(c *b.Config, db *b.DB, s *b.CookieStore) http.HandlerFunc {
|
|||||||
return func(w http.ResponseWriter, r *http.Request) {
|
return func(w http.ResponseWriter, r *http.Request) {
|
||||||
session, err := getSession(w, r, c, s)
|
session, err := getSession(w, r, c, s)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
|
log.Println(err)
|
||||||
|
http.Error(w, err.Error(), http.StatusInternalServerError)
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -416,13 +488,19 @@ func RejectArticle(c *b.Config, db *b.DB, s *b.CookieStore) http.HandlerFunc {
|
|||||||
|
|
||||||
tmpl, err := template.ParseFiles(c.WebDir + "/templates/hub.html")
|
tmpl, err := template.ParseFiles(c.WebDir + "/templates/hub.html")
|
||||||
tmpl = template.Must(tmpl, err)
|
tmpl = template.Must(tmpl, err)
|
||||||
tmpl.ExecuteTemplate(w, "page-content", session.Values["role"])
|
if err = tmpl.ExecuteTemplate(w, "page-content", session.Values["role"]); err != nil {
|
||||||
|
log.Println(err)
|
||||||
|
http.Error(w, err.Error(), http.StatusInternalServerError)
|
||||||
|
return
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
func ShowCurrentArticles(c *b.Config, db *b.DB, s *b.CookieStore) http.HandlerFunc {
|
func ShowCurrentArticles(c *b.Config, db *b.DB, s *b.CookieStore) http.HandlerFunc {
|
||||||
return func(w http.ResponseWriter, r *http.Request) {
|
return func(w http.ResponseWriter, r *http.Request) {
|
||||||
if _, err := getSession(w, r, c, s); err != nil {
|
if _, err := getSession(w, r, c, s); err != nil {
|
||||||
|
log.Println(err)
|
||||||
|
http.Error(w, err.Error(), http.StatusInternalServerError)
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -434,13 +512,19 @@ func ShowCurrentArticles(c *b.Config, db *b.DB, s *b.CookieStore) http.HandlerFu
|
|||||||
}
|
}
|
||||||
|
|
||||||
tmpl, err := template.ParseFiles(c.WebDir + "/templates/current-articles.html")
|
tmpl, err := template.ParseFiles(c.WebDir + "/templates/current-articles.html")
|
||||||
template.Must(tmpl, err).ExecuteTemplate(w, "page-content", articles)
|
if err = template.Must(tmpl, err).ExecuteTemplate(w, "page-content", articles); err != nil {
|
||||||
|
log.Println(err)
|
||||||
|
http.Error(w, err.Error(), http.StatusInternalServerError)
|
||||||
|
return
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
func UploadArticleImage(c *b.Config, s *b.CookieStore) http.HandlerFunc {
|
func UploadArticleImage(c *b.Config, s *b.CookieStore) http.HandlerFunc {
|
||||||
return func(w http.ResponseWriter, r *http.Request) {
|
return func(w http.ResponseWriter, r *http.Request) {
|
||||||
if _, err := getSession(w, r, c, s); err != nil {
|
if _, err := getSession(w, r, c, s); err != nil {
|
||||||
|
log.Println(err)
|
||||||
|
http.Error(w, err.Error(), http.StatusInternalServerError)
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -454,6 +538,10 @@ func UploadArticleImage(c *b.Config, s *b.CookieStore) http.HandlerFunc {
|
|||||||
|
|
||||||
filename, err := b.SaveImage(c, file)
|
filename, err := b.SaveImage(c, file)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
|
if err == b.ErrUnsupportedFormat {
|
||||||
|
http.Error(w, "Das Dateiformat wird nicht unterstützt.", http.StatusBadRequest)
|
||||||
|
return
|
||||||
|
}
|
||||||
log.Println(err)
|
log.Println(err)
|
||||||
http.Error(w, err.Error(), http.StatusInternalServerError)
|
http.Error(w, err.Error(), http.StatusInternalServerError)
|
||||||
return
|
return
|
||||||
@ -468,6 +556,8 @@ func UploadArticleImage(c *b.Config, s *b.CookieStore) http.HandlerFunc {
|
|||||||
func ShowPublishedArticles(c *b.Config, db *b.DB, s *b.CookieStore, action string) http.HandlerFunc {
|
func ShowPublishedArticles(c *b.Config, db *b.DB, s *b.CookieStore, action string) http.HandlerFunc {
|
||||||
return func(w http.ResponseWriter, r *http.Request) {
|
return func(w http.ResponseWriter, r *http.Request) {
|
||||||
if _, err := getSession(w, r, c, s); err != nil {
|
if _, err := getSession(w, r, c, s); err != nil {
|
||||||
|
log.Println(err)
|
||||||
|
http.Error(w, err.Error(), http.StatusInternalServerError)
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -492,13 +582,19 @@ func ShowPublishedArticles(c *b.Config, db *b.DB, s *b.CookieStore, action strin
|
|||||||
|
|
||||||
tmpl, err := template.ParseFiles(c.WebDir + "/templates/published-articles.html")
|
tmpl, err := template.ParseFiles(c.WebDir + "/templates/published-articles.html")
|
||||||
tmpl = template.Must(tmpl, err)
|
tmpl = template.Must(tmpl, err)
|
||||||
tmpl.ExecuteTemplate(w, "page-content", data)
|
if err = tmpl.ExecuteTemplate(w, "page-content", data); err != nil {
|
||||||
|
log.Println(err)
|
||||||
|
http.Error(w, err.Error(), http.StatusInternalServerError)
|
||||||
|
return
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
func ReviewArticle(c *b.Config, db *b.DB, s *b.CookieStore, action, title, button string) http.HandlerFunc {
|
func ReviewArticle(c *b.Config, db *b.DB, s *b.CookieStore, action, title, button string) http.HandlerFunc {
|
||||||
return func(w http.ResponseWriter, r *http.Request) {
|
return func(w http.ResponseWriter, r *http.Request) {
|
||||||
if _, err := getSession(w, r, c, s); err != nil {
|
if _, err := getSession(w, r, c, s); err != nil {
|
||||||
|
log.Println(err)
|
||||||
|
http.Error(w, err.Error(), http.StatusInternalServerError)
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -563,7 +659,11 @@ func ReviewArticle(c *b.Config, db *b.DB, s *b.CookieStore, action, title, butto
|
|||||||
}
|
}
|
||||||
|
|
||||||
tmpl, err := template.ParseFiles(c.WebDir + "/templates/review-article.html")
|
tmpl, err := template.ParseFiles(c.WebDir + "/templates/review-article.html")
|
||||||
template.Must(tmpl, err).ExecuteTemplate(w, "page-content", data)
|
if err = template.Must(tmpl, err).ExecuteTemplate(w, "page-content", data); err != nil {
|
||||||
|
log.Println(err)
|
||||||
|
http.Error(w, err.Error(), http.StatusInternalServerError)
|
||||||
|
return
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -571,6 +671,8 @@ func DeleteArticle(c *b.Config, db *b.DB, s *b.CookieStore) http.HandlerFunc {
|
|||||||
return func(w http.ResponseWriter, r *http.Request) {
|
return func(w http.ResponseWriter, r *http.Request) {
|
||||||
session, err := getSession(w, r, c, s)
|
session, err := getSession(w, r, c, s)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
|
log.Println(err)
|
||||||
|
http.Error(w, err.Error(), http.StatusInternalServerError)
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -607,7 +709,11 @@ func DeleteArticle(c *b.Config, db *b.DB, s *b.CookieStore) http.HandlerFunc {
|
|||||||
|
|
||||||
tmpl, err := template.ParseFiles(c.WebDir + "/templates/hub.html")
|
tmpl, err := template.ParseFiles(c.WebDir + "/templates/hub.html")
|
||||||
tmpl = template.Must(tmpl, err)
|
tmpl = template.Must(tmpl, err)
|
||||||
tmpl.ExecuteTemplate(w, "page-content", session.Values["role"].(int))
|
if err = tmpl.ExecuteTemplate(w, "page-content", session.Values["role"].(int)); err != nil {
|
||||||
|
log.Println(err)
|
||||||
|
http.Error(w, err.Error(), http.StatusInternalServerError)
|
||||||
|
return
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -615,6 +721,8 @@ func AllowEditArticle(c *b.Config, db *b.DB, s *b.CookieStore) http.HandlerFunc
|
|||||||
return func(w http.ResponseWriter, r *http.Request) {
|
return func(w http.ResponseWriter, r *http.Request) {
|
||||||
session, err := getSession(w, r, c, s)
|
session, err := getSession(w, r, c, s)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
|
log.Println(err)
|
||||||
|
http.Error(w, err.Error(), http.StatusInternalServerError)
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -659,13 +767,19 @@ func AllowEditArticle(c *b.Config, db *b.DB, s *b.CookieStore) http.HandlerFunc
|
|||||||
|
|
||||||
tmpl, err := template.ParseFiles(c.WebDir + "/templates/hub.html")
|
tmpl, err := template.ParseFiles(c.WebDir + "/templates/hub.html")
|
||||||
tmpl = template.Must(tmpl, err)
|
tmpl = template.Must(tmpl, err)
|
||||||
tmpl.ExecuteTemplate(w, "page-content", session.Values["role"].(int))
|
if err = tmpl.ExecuteTemplate(w, "page-content", session.Values["role"].(int)); err != nil {
|
||||||
|
log.Println(err)
|
||||||
|
http.Error(w, err.Error(), http.StatusInternalServerError)
|
||||||
|
return
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
func EditArticle(c *b.Config, db *b.DB, s *b.CookieStore) http.HandlerFunc {
|
func EditArticle(c *b.Config, db *b.DB, s *b.CookieStore) http.HandlerFunc {
|
||||||
return func(w http.ResponseWriter, r *http.Request) {
|
return func(w http.ResponseWriter, r *http.Request) {
|
||||||
if _, err := getSession(w, r, c, s); err != nil {
|
if _, err := getSession(w, r, c, s); err != nil {
|
||||||
|
log.Println(err)
|
||||||
|
http.Error(w, err.Error(), http.StatusInternalServerError)
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -714,6 +828,10 @@ func EditArticle(c *b.Config, db *b.DB, s *b.CookieStore) http.HandlerFunc {
|
|||||||
data.Action = fmt.Sprint("save/", data.Article.ID)
|
data.Action = fmt.Sprint("save/", data.Article.ID)
|
||||||
|
|
||||||
tmpl, err := template.ParseFiles(c.WebDir + "/templates/editor.html")
|
tmpl, err := template.ParseFiles(c.WebDir + "/templates/editor.html")
|
||||||
template.Must(tmpl, err).ExecuteTemplate(w, "page-content", data)
|
if err = template.Must(tmpl, err).ExecuteTemplate(w, "page-content", data); err != nil {
|
||||||
|
log.Println(err)
|
||||||
|
http.Error(w, err.Error(), http.StatusInternalServerError)
|
||||||
|
return
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -1,34 +0,0 @@
|
|||||||
package frontend
|
|
||||||
|
|
||||||
import (
|
|
||||||
"html/template"
|
|
||||||
"net/http"
|
|
||||||
|
|
||||||
b "streifling.com/jason/cpolis/cmd/backend"
|
|
||||||
)
|
|
||||||
|
|
||||||
func CreateTag(c *b.Config, s *b.CookieStore) http.HandlerFunc {
|
|
||||||
return func(w http.ResponseWriter, r *http.Request) {
|
|
||||||
if _, err := getSession(w, r, c, s); err != nil {
|
|
||||||
return
|
|
||||||
}
|
|
||||||
|
|
||||||
tmpl, err := template.ParseFiles(c.WebDir + "/templates/add-tag.html")
|
|
||||||
template.Must(tmpl, err).ExecuteTemplate(w, "page-content", nil)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
func AddTag(c *b.Config, db *b.DB, s *b.CookieStore) http.HandlerFunc {
|
|
||||||
return func(w http.ResponseWriter, r *http.Request) {
|
|
||||||
session, err := getSession(w, r, c, s)
|
|
||||||
if err != nil {
|
|
||||||
return
|
|
||||||
}
|
|
||||||
|
|
||||||
db.AddTag(r.PostFormValue("tag"))
|
|
||||||
|
|
||||||
tmpl, err := template.ParseFiles(c.WebDir + "/templates/hub.html")
|
|
||||||
tmpl = template.Must(tmpl, err)
|
|
||||||
tmpl.ExecuteTemplate(w, "page-content", session.Values["role"])
|
|
||||||
}
|
|
||||||
}
|
|
@ -17,6 +17,8 @@ func PublishLatestIssue(c *b.Config, db *b.DB, s *b.CookieStore) http.HandlerFun
|
|||||||
return func(w http.ResponseWriter, r *http.Request) {
|
return func(w http.ResponseWriter, r *http.Request) {
|
||||||
session, err := getSession(w, r, c, s)
|
session, err := getSession(w, r, c, s)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
|
log.Println(err)
|
||||||
|
http.Error(w, err.Error(), http.StatusInternalServerError)
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -29,21 +31,18 @@ func PublishLatestIssue(c *b.Config, db *b.DB, s *b.CookieStore) http.HandlerFun
|
|||||||
|
|
||||||
title := r.PostFormValue("issue-title")
|
title := r.PostFormValue("issue-title")
|
||||||
if len(title) == 0 {
|
if len(title) == 0 {
|
||||||
err = fmt.Errorf("error: no title for issue specified")
|
http.Error(w, "Bitte den Titel eingeben.", http.StatusBadRequest)
|
||||||
log.Println(err)
|
|
||||||
http.Error(w, err.Error(), http.StatusInternalServerError)
|
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
if session.Values["issue-image"] == nil {
|
if session.Values["issue-image"] == nil {
|
||||||
err := "error: Image required"
|
http.Error(w, "Bitte ein Bild einfügen.", http.StatusBadRequest)
|
||||||
log.Println(err)
|
|
||||||
http.Error(w, err, http.StatusBadRequest)
|
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
imgFileName := session.Values["issue-image"].(string)
|
imgFileName := session.Values["issue-image"].(string)
|
||||||
imgAbsName := fmt.Sprint(c.PicsDir, "/", imgFileName)
|
fmt.Println(imgFileName)
|
||||||
|
imgAbsName := c.PicsDir + "/" + imgFileName
|
||||||
|
|
||||||
imgFile, err := os.Open(imgAbsName)
|
imgFile, err := os.Open(imgAbsName)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
@ -79,8 +78,14 @@ func PublishLatestIssue(c *b.Config, db *b.DB, s *b.CookieStore) http.HandlerFun
|
|||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
|
content := []byte(r.PostFormValue("issue-content"))
|
||||||
|
if len(content) == 0 {
|
||||||
|
http.Error(w, "Bitte eine Beschreibung eingeben.", http.StatusBadRequest)
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
articleAbsName := fmt.Sprint(c.ArticleDir, "/", article.ID, ".md")
|
articleAbsName := fmt.Sprint(c.ArticleDir, "/", article.ID, ".md")
|
||||||
if err = os.WriteFile(articleAbsName, []byte(r.PostFormValue("article-content")), 0644); err != nil {
|
if err = os.WriteFile(articleAbsName, content, 0644); err != nil {
|
||||||
log.Println(err)
|
log.Println(err)
|
||||||
http.Error(w, err.Error(), http.StatusInternalServerError)
|
http.Error(w, err.Error(), http.StatusInternalServerError)
|
||||||
return
|
return
|
||||||
@ -132,7 +137,11 @@ func PublishLatestIssue(c *b.Config, db *b.DB, s *b.CookieStore) http.HandlerFun
|
|||||||
|
|
||||||
tmpl, err := template.ParseFiles(c.WebDir + "/templates/hub.html")
|
tmpl, err := template.ParseFiles(c.WebDir + "/templates/hub.html")
|
||||||
tmpl = template.Must(tmpl, err)
|
tmpl = template.Must(tmpl, err)
|
||||||
tmpl.ExecuteTemplate(w, "page-content", session.Values["role"])
|
if err = tmpl.ExecuteTemplate(w, "page-content", session.Values["role"]); err != nil {
|
||||||
|
log.Println(err)
|
||||||
|
http.Error(w, err.Error(), http.StatusInternalServerError)
|
||||||
|
return
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -140,6 +149,8 @@ func UploadIssueImage(c *b.Config, s *b.CookieStore) http.HandlerFunc {
|
|||||||
return func(w http.ResponseWriter, r *http.Request) {
|
return func(w http.ResponseWriter, r *http.Request) {
|
||||||
session, err := getSession(w, r, c, s)
|
session, err := getSession(w, r, c, s)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
|
log.Println(err)
|
||||||
|
http.Error(w, err.Error(), http.StatusInternalServerError)
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -159,6 +170,10 @@ func UploadIssueImage(c *b.Config, s *b.CookieStore) http.HandlerFunc {
|
|||||||
|
|
||||||
filename, err := b.SaveImage(c, file)
|
filename, err := b.SaveImage(c, file)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
|
if err == b.ErrUnsupportedFormat {
|
||||||
|
http.Error(w, "Das Dateiformat wird nicht unterstützt.", http.StatusBadRequest)
|
||||||
|
return
|
||||||
|
}
|
||||||
log.Println(err)
|
log.Println(err)
|
||||||
http.Error(w, err.Error(), http.StatusInternalServerError)
|
http.Error(w, err.Error(), http.StatusInternalServerError)
|
||||||
return
|
return
|
||||||
|
@ -15,6 +15,8 @@ import (
|
|||||||
func UploadPDF(c *b.Config, s *b.CookieStore) http.HandlerFunc {
|
func UploadPDF(c *b.Config, s *b.CookieStore) http.HandlerFunc {
|
||||||
return func(w http.ResponseWriter, r *http.Request) {
|
return func(w http.ResponseWriter, r *http.Request) {
|
||||||
if _, err := getSession(w, r, c, s); err != nil {
|
if _, err := getSession(w, r, c, s); err != nil {
|
||||||
|
log.Println(err)
|
||||||
|
http.Error(w, err.Error(), http.StatusInternalServerError)
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -32,6 +34,24 @@ func UploadPDF(c *b.Config, s *b.CookieStore) http.HandlerFunc {
|
|||||||
}
|
}
|
||||||
defer file.Close()
|
defer file.Close()
|
||||||
|
|
||||||
|
buffer := make([]byte, 512) // Should be enough for mime type
|
||||||
|
if _, err := file.Read(buffer); err != nil {
|
||||||
|
log.Println(err)
|
||||||
|
http.Error(w, err.Error(), http.StatusInternalServerError)
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
if _, err := file.Seek(0, 0); err != nil {
|
||||||
|
log.Println(err)
|
||||||
|
http.Error(w, err.Error(), http.StatusInternalServerError)
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
if http.DetectContentType(buffer) != "application/pdf" {
|
||||||
|
http.Error(w, "Die Datei ist kein PDF.", http.StatusInternalServerError)
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
filename := fmt.Sprint(uuid.New(), ".pdf")
|
filename := fmt.Sprint(uuid.New(), ".pdf")
|
||||||
absFilepath, err := filepath.Abs(fmt.Sprint(c.PDFDir, "/", filename))
|
absFilepath, err := filepath.Abs(fmt.Sprint(c.PDFDir, "/", filename))
|
||||||
if err != nil {
|
if err != nil {
|
||||||
|
@ -1,7 +1,6 @@
|
|||||||
package frontend
|
package frontend
|
||||||
|
|
||||||
import (
|
import (
|
||||||
"errors"
|
|
||||||
"fmt"
|
"fmt"
|
||||||
"html/template"
|
"html/template"
|
||||||
"log"
|
"log"
|
||||||
@ -34,14 +33,17 @@ func getSession(w http.ResponseWriter, r *http.Request, c *b.Config, s *b.Cookie
|
|||||||
|
|
||||||
tmpSession, err := s.Get(r, "cookie")
|
tmpSession, err := s.Get(r, "cookie")
|
||||||
if err != nil {
|
if err != nil {
|
||||||
template.Must(tmpl, tmplErr).ExecuteTemplate(w, "page-content", msg)
|
if err = template.Must(tmpl, tmplErr).ExecuteTemplate(w, "page-content", msg); err != nil {
|
||||||
return nil, err
|
return nil, fmt.Errorf("error executing template: %v", err)
|
||||||
|
}
|
||||||
|
return nil, fmt.Errorf("error getting session: %v", err)
|
||||||
}
|
}
|
||||||
|
|
||||||
session := &b.Session{Session: *tmpSession}
|
session := &b.Session{Session: *tmpSession}
|
||||||
if session.IsNew {
|
if session.IsNew {
|
||||||
template.Must(tmpl, tmplErr).ExecuteTemplate(w, "page-content", msg)
|
if err = template.Must(tmpl, tmplErr).ExecuteTemplate(w, "page-content", msg); err != nil {
|
||||||
return session, errors.New("error: no existing session")
|
return nil, fmt.Errorf("error executing template: %v", err)
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
return session, nil
|
return session, nil
|
||||||
@ -54,21 +56,39 @@ func HomePage(c *b.Config, db *b.DB, s *b.CookieStore) http.HandlerFunc {
|
|||||||
log.Fatalln(err)
|
log.Fatalln(err)
|
||||||
}
|
}
|
||||||
|
|
||||||
files := []string{c.WebDir + "/templates/index.html"}
|
files := make([]string, 2)
|
||||||
|
files[0] = c.WebDir + "/templates/index.html"
|
||||||
if numRows == 0 {
|
if numRows == 0 {
|
||||||
files = append(files, c.WebDir+"/templates/first-user.html")
|
files[1] = c.WebDir + "/templates/first-user.html"
|
||||||
tmpl, err := template.ParseFiles(files...)
|
tmpl, err := template.ParseFiles(files...)
|
||||||
template.Must(tmpl, err).Execute(w, nil)
|
if err = template.Must(tmpl, err).Execute(w, nil); err != nil {
|
||||||
|
log.Println(err)
|
||||||
|
http.Error(w, err.Error(), http.StatusInternalServerError)
|
||||||
|
return
|
||||||
|
}
|
||||||
} else {
|
} else {
|
||||||
session, _ := s.Get(r, "cookie")
|
session, err := s.Get(r, "cookie")
|
||||||
|
if err != nil {
|
||||||
|
log.Println(err)
|
||||||
|
http.Error(w, err.Error(), http.StatusInternalServerError)
|
||||||
|
return
|
||||||
|
}
|
||||||
if auth, ok := session.Values["authenticated"].(bool); auth && ok {
|
if auth, ok := session.Values["authenticated"].(bool); auth && ok {
|
||||||
files = append(files, c.WebDir+"/templates/hub.html")
|
files[1] = c.WebDir + "/templates/hub.html"
|
||||||
tmpl, err := template.ParseFiles(files...)
|
tmpl, err := template.ParseFiles(files...)
|
||||||
template.Must(tmpl, err).Execute(w, session.Values["role"])
|
if err = template.Must(tmpl, err).Execute(w, session.Values["role"]); err != nil {
|
||||||
|
log.Println(err)
|
||||||
|
http.Error(w, err.Error(), http.StatusInternalServerError)
|
||||||
|
return
|
||||||
|
}
|
||||||
} else {
|
} else {
|
||||||
files = append(files, c.WebDir+"/templates/login.html")
|
files[1] = c.WebDir + "/templates/login.html"
|
||||||
tmpl, err := template.ParseFiles(files...)
|
tmpl, err := template.ParseFiles(files...)
|
||||||
template.Must(tmpl, err).Execute(w, nil)
|
if err = template.Must(tmpl, err).Execute(w, nil); err != nil {
|
||||||
|
log.Println(err)
|
||||||
|
http.Error(w, err.Error(), http.StatusInternalServerError)
|
||||||
|
return
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -79,8 +99,8 @@ func Login(c *b.Config, db *b.DB, s *b.CookieStore) http.HandlerFunc {
|
|||||||
userName := r.PostFormValue("username")
|
userName := r.PostFormValue("username")
|
||||||
password := r.PostFormValue("password")
|
password := r.PostFormValue("password")
|
||||||
|
|
||||||
id, ok := db.GetID(userName)
|
id := db.GetID(userName)
|
||||||
if !ok {
|
if id == 0 {
|
||||||
http.Error(w, fmt.Sprintf("no such user: %v", userName), http.StatusBadRequest)
|
http.Error(w, fmt.Sprintf("no such user: %v", userName), http.StatusBadRequest)
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
@ -105,7 +125,11 @@ func Login(c *b.Config, db *b.DB, s *b.CookieStore) http.HandlerFunc {
|
|||||||
}
|
}
|
||||||
|
|
||||||
tmpl, err := template.ParseFiles(c.WebDir + "/templates/hub.html")
|
tmpl, err := template.ParseFiles(c.WebDir + "/templates/hub.html")
|
||||||
template.Must(tmpl, err).ExecuteTemplate(w, "page-content", user.Role)
|
if err = template.Must(tmpl, err).ExecuteTemplate(w, "page-content", user.Role); err != nil {
|
||||||
|
log.Println(err)
|
||||||
|
http.Error(w, err.Error(), http.StatusInternalServerError)
|
||||||
|
return
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -113,6 +137,8 @@ func Logout(c *b.Config, s *b.CookieStore) http.HandlerFunc {
|
|||||||
return func(w http.ResponseWriter, r *http.Request) {
|
return func(w http.ResponseWriter, r *http.Request) {
|
||||||
session, err := getSession(w, r, c, s)
|
session, err := getSession(w, r, c, s)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
|
log.Println(err)
|
||||||
|
http.Error(w, err.Error(), http.StatusInternalServerError)
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -124,7 +150,11 @@ func Logout(c *b.Config, s *b.CookieStore) http.HandlerFunc {
|
|||||||
}
|
}
|
||||||
|
|
||||||
tmpl, err := template.ParseFiles(c.WebDir + "/templates/login.html")
|
tmpl, err := template.ParseFiles(c.WebDir + "/templates/login.html")
|
||||||
template.Must(tmpl, err).ExecuteTemplate(w, "page-content", nil)
|
if err = template.Must(tmpl, err).ExecuteTemplate(w, "page-content", nil); err != nil {
|
||||||
|
log.Println(err)
|
||||||
|
http.Error(w, err.Error(), http.StatusInternalServerError)
|
||||||
|
return
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -132,6 +162,8 @@ func ShowHub(c *b.Config, db *b.DB, s *b.CookieStore) http.HandlerFunc {
|
|||||||
return func(w http.ResponseWriter, r *http.Request) {
|
return func(w http.ResponseWriter, r *http.Request) {
|
||||||
session, err := getSession(w, r, c, s)
|
session, err := getSession(w, r, c, s)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
|
log.Println(err)
|
||||||
|
http.Error(w, err.Error(), http.StatusInternalServerError)
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -143,6 +175,10 @@ func ShowHub(c *b.Config, db *b.DB, s *b.CookieStore) http.HandlerFunc {
|
|||||||
}
|
}
|
||||||
|
|
||||||
tmpl, err := template.ParseFiles(c.WebDir + "/templates/hub.html")
|
tmpl, err := template.ParseFiles(c.WebDir + "/templates/hub.html")
|
||||||
template.Must(tmpl, err).ExecuteTemplate(w, "page-content", session.Values["role"].(int))
|
if err = template.Must(tmpl, err).ExecuteTemplate(w, "page-content", session.Values["role"].(int)); err != nil {
|
||||||
|
log.Println(err)
|
||||||
|
http.Error(w, err.Error(), http.StatusInternalServerError)
|
||||||
|
return
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
52
cmd/frontend/tags.go
Normal file
52
cmd/frontend/tags.go
Normal file
@ -0,0 +1,52 @@
|
|||||||
|
package frontend
|
||||||
|
|
||||||
|
import (
|
||||||
|
"html/template"
|
||||||
|
"log"
|
||||||
|
"net/http"
|
||||||
|
|
||||||
|
b "streifling.com/jason/cpolis/cmd/backend"
|
||||||
|
)
|
||||||
|
|
||||||
|
func CreateTag(c *b.Config, s *b.CookieStore) http.HandlerFunc {
|
||||||
|
return func(w http.ResponseWriter, r *http.Request) {
|
||||||
|
if _, err := getSession(w, r, c, s); err != nil {
|
||||||
|
log.Println(err)
|
||||||
|
http.Error(w, err.Error(), http.StatusInternalServerError)
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
tmpl, err := template.ParseFiles(c.WebDir + "/templates/add-tag.html")
|
||||||
|
if err = template.Must(tmpl, err).ExecuteTemplate(w, "page-content", nil); err != nil {
|
||||||
|
log.Println(err)
|
||||||
|
http.Error(w, err.Error(), http.StatusInternalServerError)
|
||||||
|
return
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
func AddTag(c *b.Config, db *b.DB, s *b.CookieStore) http.HandlerFunc {
|
||||||
|
return func(w http.ResponseWriter, r *http.Request) {
|
||||||
|
session, err := getSession(w, r, c, s)
|
||||||
|
if err != nil {
|
||||||
|
log.Println(err)
|
||||||
|
http.Error(w, err.Error(), http.StatusInternalServerError)
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
tag := r.PostFormValue("tag")
|
||||||
|
if len(tag) == 0 {
|
||||||
|
http.Error(w, "Bitte einen Tag eingeben.", http.StatusBadRequest)
|
||||||
|
return
|
||||||
|
}
|
||||||
|
db.AddTag(tag)
|
||||||
|
|
||||||
|
tmpl, err := template.ParseFiles(c.WebDir + "/templates/hub.html")
|
||||||
|
tmpl = template.Must(tmpl, err)
|
||||||
|
if err = tmpl.ExecuteTemplate(w, "page-content", session.Values["role"]); err != nil {
|
||||||
|
log.Println(err)
|
||||||
|
http.Error(w, err.Error(), http.StatusInternalServerError)
|
||||||
|
return
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
@ -10,11 +10,6 @@ import (
|
|||||||
b "streifling.com/jason/cpolis/cmd/backend"
|
b "streifling.com/jason/cpolis/cmd/backend"
|
||||||
)
|
)
|
||||||
|
|
||||||
type UserData struct {
|
|
||||||
*b.User
|
|
||||||
Msg string
|
|
||||||
}
|
|
||||||
|
|
||||||
func checkUserStrings(user *b.User) (string, int, bool) {
|
func checkUserStrings(user *b.User) (string, int, bool) {
|
||||||
userLen := 15
|
userLen := 15
|
||||||
nameLen := 50
|
nameLen := 50
|
||||||
@ -33,11 +28,17 @@ func checkUserStrings(user *b.User) (string, int, bool) {
|
|||||||
func CreateUser(c *b.Config, s *b.CookieStore) http.HandlerFunc {
|
func CreateUser(c *b.Config, s *b.CookieStore) http.HandlerFunc {
|
||||||
return func(w http.ResponseWriter, r *http.Request) {
|
return func(w http.ResponseWriter, r *http.Request) {
|
||||||
if _, err := getSession(w, r, c, s); err != nil {
|
if _, err := getSession(w, r, c, s); err != nil {
|
||||||
|
log.Println(err)
|
||||||
|
http.Error(w, err.Error(), http.StatusInternalServerError)
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
tmpl, err := template.ParseFiles(c.WebDir + "/templates/add-user.html")
|
tmpl, err := template.ParseFiles(c.WebDir + "/templates/add-user.html")
|
||||||
template.Must(tmpl, err).ExecuteTemplate(w, "page-content", nil)
|
if err = template.Must(tmpl, err).ExecuteTemplate(w, "page-content", nil); err != nil {
|
||||||
|
log.Println(err)
|
||||||
|
http.Error(w, err.Error(), http.StatusInternalServerError)
|
||||||
|
return
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -45,58 +46,55 @@ func AddUser(c *b.Config, db *b.DB, s *b.CookieStore) http.HandlerFunc {
|
|||||||
return func(w http.ResponseWriter, r *http.Request) {
|
return func(w http.ResponseWriter, r *http.Request) {
|
||||||
session, err := getSession(w, r, c, s)
|
session, err := getSession(w, r, c, s)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
|
log.Println(err)
|
||||||
|
http.Error(w, err.Error(), http.StatusInternalServerError)
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
role, err := strconv.Atoi(r.PostFormValue("role"))
|
user := &b.User{
|
||||||
|
UserName: r.PostFormValue("username"),
|
||||||
|
FirstName: r.PostFormValue("first-name"),
|
||||||
|
LastName: r.PostFormValue("last-name"),
|
||||||
|
}
|
||||||
|
pass := r.PostFormValue("password")
|
||||||
|
pass2 := r.PostFormValue("password2")
|
||||||
|
|
||||||
|
if len(user.UserName) == 0 || len(user.FirstName) == 0 ||
|
||||||
|
len(user.LastName) == 0 || len(pass) == 0 || len(pass2) == 0 {
|
||||||
|
http.Error(w, "Bitte alle Felder ausfüllen.", http.StatusBadRequest)
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
userString, stringLen, ok := checkUserStrings(user)
|
||||||
|
if !ok {
|
||||||
|
http.Error(w, fmt.Sprint(userString, " ist zu lang. Maximal ", stringLen, " Zeichen erlaubt."), http.StatusBadRequest)
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
if id := db.GetID(user.UserName); id != 0 {
|
||||||
|
http.Error(w, user.UserName+" ist bereits vergeben. Bitte anderen Benutzernamen wählen.", http.StatusBadRequest)
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
if pass != pass2 {
|
||||||
|
http.Error(w, "Die Passwörter stimmen nicht überein.", http.StatusBadRequest)
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
roleString := r.PostFormValue("role")
|
||||||
|
if len(roleString) == 0 {
|
||||||
|
http.Error(w, "Bitte eine Aufgabe vergeben.", http.StatusBadRequest)
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
user.Role, err = strconv.Atoi(roleString)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
log.Println(err)
|
log.Println(err)
|
||||||
http.Error(w, err.Error(), http.StatusInternalServerError)
|
http.Error(w, err.Error(), http.StatusInternalServerError)
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
htmlData := UserData{
|
_, err = db.AddUser(user, pass)
|
||||||
User: &b.User{
|
|
||||||
UserName: r.PostFormValue("username"),
|
|
||||||
FirstName: r.PostFormValue("first-name"),
|
|
||||||
LastName: r.PostFormValue("last-name"),
|
|
||||||
Role: role,
|
|
||||||
},
|
|
||||||
}
|
|
||||||
pass := r.PostFormValue("password")
|
|
||||||
pass2 := r.PostFormValue("password2")
|
|
||||||
|
|
||||||
if len(htmlData.UserName) == 0 || len(htmlData.FirstName) == 0 ||
|
|
||||||
len(htmlData.LastName) == 0 || len(pass) == 0 || len(pass2) == 0 {
|
|
||||||
htmlData.Msg = "Alle Felder müssen ausgefüllt werden."
|
|
||||||
tmpl, err := template.ParseFiles(c.WebDir + "/templates/add-user.html")
|
|
||||||
template.Must(tmpl, err).ExecuteTemplate(w, "page-content", htmlData)
|
|
||||||
return
|
|
||||||
}
|
|
||||||
userString, stringLen, ok := checkUserStrings(htmlData.User)
|
|
||||||
if !ok {
|
|
||||||
htmlData.Msg = fmt.Sprint(userString, " ist zu lang. Maximal ",
|
|
||||||
stringLen, " Zeichen erlaubt.")
|
|
||||||
tmpl, err := template.ParseFiles(c.WebDir + "/templates/add-user.html")
|
|
||||||
template.Must(tmpl, err).ExecuteTemplate(w, "page-content", htmlData)
|
|
||||||
return
|
|
||||||
}
|
|
||||||
id, _ := db.GetID(htmlData.UserName)
|
|
||||||
if id != 0 {
|
|
||||||
htmlData.Msg = fmt.Sprint(htmlData.UserName,
|
|
||||||
" ist bereits vergeben. Bitte anderen Benutzernamen wählen.")
|
|
||||||
tmpl, err := template.ParseFiles(c.WebDir + "/templates/add-user.html")
|
|
||||||
template.Must(tmpl, err).ExecuteTemplate(w, "page-content", htmlData)
|
|
||||||
return
|
|
||||||
}
|
|
||||||
if pass != pass2 {
|
|
||||||
htmlData.Msg = "Die Passwörter stimmen nicht überein."
|
|
||||||
tmpl, err := template.ParseFiles(c.WebDir + "/templates/add-user.html")
|
|
||||||
template.Must(tmpl, err).ExecuteTemplate(w, "page-content", htmlData)
|
|
||||||
return
|
|
||||||
}
|
|
||||||
|
|
||||||
_, err = db.AddUser(htmlData.User, pass)
|
|
||||||
if err != nil {
|
if err != nil {
|
||||||
log.Println(err)
|
log.Println(err)
|
||||||
http.Error(w, err.Error(), http.StatusInternalServerError)
|
http.Error(w, err.Error(), http.StatusInternalServerError)
|
||||||
@ -105,7 +103,11 @@ func AddUser(c *b.Config, db *b.DB, s *b.CookieStore) http.HandlerFunc {
|
|||||||
|
|
||||||
tmpl, err := template.ParseFiles(c.WebDir + "/templates/hub.html")
|
tmpl, err := template.ParseFiles(c.WebDir + "/templates/hub.html")
|
||||||
tmpl = template.Must(tmpl, err)
|
tmpl = template.Must(tmpl, err)
|
||||||
tmpl.ExecuteTemplate(w, "page-content", session.Values["role"].(int))
|
if err = tmpl.ExecuteTemplate(w, "page-content", session.Values["role"].(int)); err != nil {
|
||||||
|
log.Println(err)
|
||||||
|
http.Error(w, err.Error(), http.StatusInternalServerError)
|
||||||
|
return
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -113,6 +115,8 @@ func EditSelf(c *b.Config, db *b.DB, s *b.CookieStore) http.HandlerFunc {
|
|||||||
return func(w http.ResponseWriter, r *http.Request) {
|
return func(w http.ResponseWriter, r *http.Request) {
|
||||||
session, err := getSession(w, r, c, s)
|
session, err := getSession(w, r, c, s)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
|
log.Println(err)
|
||||||
|
http.Error(w, err.Error(), http.StatusInternalServerError)
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -124,7 +128,11 @@ func EditSelf(c *b.Config, db *b.DB, s *b.CookieStore) http.HandlerFunc {
|
|||||||
}
|
}
|
||||||
|
|
||||||
tmpl, err := template.ParseFiles(c.WebDir + "/templates/edit-self.html")
|
tmpl, err := template.ParseFiles(c.WebDir + "/templates/edit-self.html")
|
||||||
template.Must(tmpl, err).ExecuteTemplate(w, "page-content", user)
|
if err = template.Must(tmpl, err).ExecuteTemplate(w, "page-content", user); err != nil {
|
||||||
|
log.Println(err)
|
||||||
|
http.Error(w, err.Error(), http.StatusInternalServerError)
|
||||||
|
return
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -132,128 +140,100 @@ func UpdateSelf(c *b.Config, db *b.DB, s *b.CookieStore) http.HandlerFunc {
|
|||||||
return func(w http.ResponseWriter, r *http.Request) {
|
return func(w http.ResponseWriter, r *http.Request) {
|
||||||
session, err := getSession(w, r, c, s)
|
session, err := getSession(w, r, c, s)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
|
log.Println(err)
|
||||||
|
http.Error(w, err.Error(), http.StatusInternalServerError)
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
userData := UserData{
|
user := &b.User{
|
||||||
User: &b.User{
|
|
||||||
ID: session.Values["id"].(int64),
|
ID: session.Values["id"].(int64),
|
||||||
UserName: r.PostFormValue("username"),
|
UserName: r.PostFormValue("username"),
|
||||||
FirstName: r.PostFormValue("first-name"),
|
FirstName: r.PostFormValue("first-name"),
|
||||||
LastName: r.PostFormValue("last-name"),
|
LastName: r.PostFormValue("last-name"),
|
||||||
},
|
|
||||||
}
|
}
|
||||||
|
|
||||||
oldPass := r.PostFormValue("old-password")
|
oldPass := r.PostFormValue("old-password")
|
||||||
newPass := r.PostFormValue("password")
|
newPass := r.PostFormValue("password")
|
||||||
newPass2 := r.PostFormValue("password2")
|
newPass2 := r.PostFormValue("password2")
|
||||||
|
|
||||||
if len(userData.UserName) == 0 || len(userData.FirstName) == 0 ||
|
if len(user.UserName) == 0 {
|
||||||
len(userData.LastName) == 0 {
|
http.Error(w, "Bitte den Benutzernamen ausfüllen.", http.StatusBadRequest)
|
||||||
userData.Msg = "Alle Felder mit * müssen ausgefüllt sein."
|
|
||||||
tmpl, err := template.ParseFiles(c.WebDir + "/templates/edit-user.html")
|
|
||||||
tmpl = template.Must(tmpl, err)
|
|
||||||
tmpl.ExecuteTemplate(w, "page-content", userData.Msg)
|
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
userString, stringLen, ok := checkUserStrings(userData.User)
|
if len(user.FirstName) == 0 || len(user.LastName) == 0 {
|
||||||
|
http.Error(w, "Bitte den vollständigen Namen ausfüllen.", http.StatusBadRequest)
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
userString, stringLen, ok := checkUserStrings(user)
|
||||||
if !ok {
|
if !ok {
|
||||||
userData.Msg = fmt.Sprint(userString, " ist zu lang. Maximal ",
|
http.Error(w, fmt.Sprint(userString, " ist zu lang. Maximal ", stringLen, " Zeichen erlaubt."), http.StatusBadRequest)
|
||||||
stringLen, " Zeichen erlaubt.")
|
|
||||||
tmpl, err := template.ParseFiles(c.WebDir + "/templates/edit-user.html")
|
|
||||||
tmpl = template.Must(tmpl, err)
|
|
||||||
tmpl.ExecuteTemplate(w, "page-content", userData)
|
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
if id, ok := db.GetID(userData.UserName); ok {
|
if id := db.GetID(user.UserName); id != 0 && id != user.ID {
|
||||||
if id != userData.ID {
|
http.Error(w, user.UserName+" ist bereits vergeben. Bitte anderen Benutzernamen wählen.", http.StatusBadRequest)
|
||||||
userData.Msg = "Benutzername bereits vergeben."
|
|
||||||
userData.UserName = ""
|
|
||||||
tmpl, err := template.ParseFiles(c.WebDir + "/templates/edit-user.html")
|
|
||||||
tmpl = template.Must(tmpl, err)
|
|
||||||
tmpl.ExecuteTemplate(w, "page-content", userData)
|
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
}
|
|
||||||
|
|
||||||
if err = db.UpdateOwnAttributes(
|
if err = db.UpdateOwnUserAttributes(user.ID, user.UserName, user.FirstName, user.LastName, oldPass, newPass, newPass2); err != nil {
|
||||||
userData.ID,
|
log.Println("error: user:", user.ID, err)
|
||||||
userData.UserName,
|
http.Error(w, "Benutzerdaten konnten nicht aktualisiert werden.", http.StatusInternalServerError)
|
||||||
userData.FirstName,
|
return
|
||||||
userData.LastName,
|
|
||||||
oldPass,
|
|
||||||
newPass,
|
|
||||||
newPass2); err != nil {
|
|
||||||
userData.Msg = "Aktualisierung der Benutzerdaten fehlgeschlagen."
|
|
||||||
tmpl, err := template.ParseFiles(c.WebDir + "/templates/edit-user.html")
|
|
||||||
template.Must(tmpl, err).ExecuteTemplate(w, "page-content", userData)
|
|
||||||
}
|
}
|
||||||
|
|
||||||
tmpl, err := template.ParseFiles(c.WebDir + "/templates/hub.html")
|
tmpl, err := template.ParseFiles(c.WebDir + "/templates/hub.html")
|
||||||
tmpl = template.Must(tmpl, err)
|
tmpl = template.Must(tmpl, err)
|
||||||
tmpl.ExecuteTemplate(w, "page-content", session.Values["role"].(int))
|
if err = tmpl.ExecuteTemplate(w, "page-content", session.Values["role"].(int)); err != nil {
|
||||||
|
log.Println(err)
|
||||||
|
http.Error(w, err.Error(), http.StatusInternalServerError)
|
||||||
|
return
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
func AddFirstUser(c *b.Config, db *b.DB, s *b.CookieStore) http.HandlerFunc {
|
func AddFirstUser(c *b.Config, db *b.DB, s *b.CookieStore) http.HandlerFunc {
|
||||||
return func(w http.ResponseWriter, r *http.Request) {
|
return func(w http.ResponseWriter, r *http.Request) {
|
||||||
var err error
|
var err error
|
||||||
htmlData := UserData{
|
user := &b.User{
|
||||||
User: &b.User{
|
|
||||||
UserName: r.PostFormValue("username"),
|
UserName: r.PostFormValue("username"),
|
||||||
FirstName: r.PostFormValue("first-name"),
|
FirstName: r.PostFormValue("first-name"),
|
||||||
LastName: r.PostFormValue("last-name"),
|
LastName: r.PostFormValue("last-name"),
|
||||||
Role: b.Admin,
|
Role: b.Admin,
|
||||||
},
|
|
||||||
}
|
}
|
||||||
pass := r.PostFormValue("password")
|
pass := r.PostFormValue("password")
|
||||||
pass2 := r.PostFormValue("password2")
|
pass2 := r.PostFormValue("password2")
|
||||||
|
|
||||||
if len(htmlData.UserName) == 0 || len(htmlData.FirstName) == 0 ||
|
if len(user.UserName) == 0 || len(user.FirstName) == 0 ||
|
||||||
len(htmlData.LastName) == 0 || len(pass) == 0 || len(pass2) == 0 {
|
len(user.LastName) == 0 || len(pass) == 0 || len(pass2) == 0 {
|
||||||
htmlData.Msg = "Alle Felder müssen ausgefüllt werden."
|
http.Error(w, "Bitte alle Felder ausfüllen.", http.StatusBadRequest)
|
||||||
tmpl, err := template.ParseFiles(c.WebDir + "/templates/add-user.html")
|
|
||||||
template.Must(tmpl, err).ExecuteTemplate(w, "page-content", htmlData)
|
|
||||||
return
|
|
||||||
}
|
|
||||||
userString, stringLen, ok := checkUserStrings(htmlData.User)
|
|
||||||
if !ok {
|
|
||||||
htmlData.Msg = fmt.Sprint(userString, " ist zu lang. Maximal ",
|
|
||||||
stringLen, " Zeichen erlaubt.")
|
|
||||||
tmpl, err := template.ParseFiles(c.WebDir + "/templates/add-user.html")
|
|
||||||
template.Must(tmpl, err).ExecuteTemplate(w, "page-content", htmlData)
|
|
||||||
return
|
|
||||||
}
|
|
||||||
id, _ := db.GetID(htmlData.UserName)
|
|
||||||
if id != 0 {
|
|
||||||
htmlData.Msg = fmt.Sprint(htmlData.UserName,
|
|
||||||
" ist bereits vergeben. Bitte anderen Benutzernamen wählen.")
|
|
||||||
tmpl, err := template.ParseFiles(c.WebDir + "/templates/add-user.html")
|
|
||||||
template.Must(tmpl, err).ExecuteTemplate(w, "page-content", htmlData)
|
|
||||||
return
|
|
||||||
}
|
|
||||||
if pass != pass2 {
|
|
||||||
htmlData.Msg = "Die Passwörter stimmen nicht überein."
|
|
||||||
tmpl, err := template.ParseFiles(c.WebDir + "/templates/add-user.html")
|
|
||||||
template.Must(tmpl, err).ExecuteTemplate(w, "page-content", htmlData)
|
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
htmlData.ID, err = db.AddFirstUser(htmlData.User, pass)
|
userString, stringLen, ok := checkUserStrings(user)
|
||||||
|
if !ok {
|
||||||
|
http.Error(w, fmt.Sprint(userString, " ist zu lang. Maximal ", stringLen, " Zeichen erlaubt."), http.StatusBadRequest)
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
if pass != pass2 {
|
||||||
|
http.Error(w, "Die Passwörter stimmen nicht überein.", http.StatusBadRequest)
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
user.ID, err = db.AddFirstUser(user, pass)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
log.Println(err)
|
log.Println(err)
|
||||||
http.Error(w, err.Error(), http.StatusInternalServerError)
|
http.Error(w, err.Error(), http.StatusInternalServerError)
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
if htmlData.ID > 1 {
|
if user.ID == -1 {
|
||||||
errString := "error: there is already a first user"
|
http.Error(w, "Bitte ein Benutzerkonto von einem Administrator anlegen lassen.", http.StatusInternalServerError)
|
||||||
log.Println(errString)
|
|
||||||
http.Error(w, errString, http.StatusInternalServerError)
|
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
if err := saveSession(w, r, s, htmlData.User); err != nil {
|
if err := saveSession(w, r, s, user); err != nil {
|
||||||
log.Println(err)
|
log.Println(err)
|
||||||
http.Error(w, err.Error(), http.StatusInternalServerError)
|
http.Error(w, err.Error(), http.StatusInternalServerError)
|
||||||
return
|
return
|
||||||
@ -266,7 +246,11 @@ func AddFirstUser(c *b.Config, db *b.DB, s *b.CookieStore) http.HandlerFunc {
|
|||||||
}
|
}
|
||||||
|
|
||||||
tmpl, err := template.ParseFiles(c.WebDir + "/templates/hub.html")
|
tmpl, err := template.ParseFiles(c.WebDir + "/templates/hub.html")
|
||||||
template.Must(tmpl, err).ExecuteTemplate(w, "page-content", 0)
|
if err = template.Must(tmpl, err).ExecuteTemplate(w, "page-content", 0); err != nil {
|
||||||
|
log.Println(err)
|
||||||
|
http.Error(w, err.Error(), http.StatusInternalServerError)
|
||||||
|
return
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -274,6 +258,8 @@ func ShowAllUsers(c *b.Config, db *b.DB, s *b.CookieStore, action string) http.H
|
|||||||
return func(w http.ResponseWriter, r *http.Request) {
|
return func(w http.ResponseWriter, r *http.Request) {
|
||||||
session, err := getSession(w, r, c, s)
|
session, err := getSession(w, r, c, s)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
|
log.Println(err)
|
||||||
|
http.Error(w, err.Error(), http.StatusInternalServerError)
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -292,13 +278,19 @@ func ShowAllUsers(c *b.Config, db *b.DB, s *b.CookieStore, action string) http.H
|
|||||||
|
|
||||||
delete(data.Users, session.Values["id"].(int64))
|
delete(data.Users, session.Values["id"].(int64))
|
||||||
tmpl, err := template.ParseFiles(c.WebDir + "/templates/show-all-users.html")
|
tmpl, err := template.ParseFiles(c.WebDir + "/templates/show-all-users.html")
|
||||||
template.Must(tmpl, err).ExecuteTemplate(w, "page-content", data)
|
if err = template.Must(tmpl, err).ExecuteTemplate(w, "page-content", data); err != nil {
|
||||||
|
log.Println(err)
|
||||||
|
http.Error(w, err.Error(), http.StatusInternalServerError)
|
||||||
|
return
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
func EditUser(c *b.Config, db *b.DB, s *b.CookieStore) http.HandlerFunc {
|
func EditUser(c *b.Config, db *b.DB, s *b.CookieStore) http.HandlerFunc {
|
||||||
return func(w http.ResponseWriter, r *http.Request) {
|
return func(w http.ResponseWriter, r *http.Request) {
|
||||||
if _, err := getSession(w, r, c, s); err != nil {
|
if _, err := getSession(w, r, c, s); err != nil {
|
||||||
|
log.Println(err)
|
||||||
|
http.Error(w, err.Error(), http.StatusInternalServerError)
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -317,7 +309,11 @@ func EditUser(c *b.Config, db *b.DB, s *b.CookieStore) http.HandlerFunc {
|
|||||||
}
|
}
|
||||||
|
|
||||||
tmpl, err := template.ParseFiles(c.WebDir + "/templates/edit-user.html")
|
tmpl, err := template.ParseFiles(c.WebDir + "/templates/edit-user.html")
|
||||||
template.Must(tmpl, err).ExecuteTemplate(w, "page-content", user)
|
if err = template.Must(tmpl, err).ExecuteTemplate(w, "page-content", user); err != nil {
|
||||||
|
log.Println(err)
|
||||||
|
http.Error(w, err.Error(), http.StatusInternalServerError)
|
||||||
|
return
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -325,81 +321,65 @@ func UpdateUser(c *b.Config, db *b.DB, s *b.CookieStore) http.HandlerFunc {
|
|||||||
return func(w http.ResponseWriter, r *http.Request) {
|
return func(w http.ResponseWriter, r *http.Request) {
|
||||||
session, err := getSession(w, r, c, s)
|
session, err := getSession(w, r, c, s)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
|
log.Println(err)
|
||||||
|
http.Error(w, err.Error(), http.StatusInternalServerError)
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
id, err := strconv.ParseInt(r.PathValue("id"), 10, 64)
|
user := new(b.User)
|
||||||
|
user.ID, err = strconv.ParseInt(r.PathValue("id"), 10, 64)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
log.Println(err)
|
log.Println(err)
|
||||||
http.Error(w, err.Error(), http.StatusInternalServerError)
|
http.Error(w, err.Error(), http.StatusInternalServerError)
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
role, err := strconv.Atoi(r.PostFormValue("role"))
|
user.Role, err = strconv.Atoi(r.PostFormValue("role"))
|
||||||
if err != nil {
|
if err != nil {
|
||||||
log.Println(err)
|
log.Println(err)
|
||||||
http.Error(w, err.Error(), http.StatusInternalServerError)
|
http.Error(w, err.Error(), http.StatusInternalServerError)
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
userData := UserData{
|
user.UserName = r.PostFormValue("username")
|
||||||
User: &b.User{
|
if len(user.UserName) == 0 {
|
||||||
ID: id,
|
http.Error(w, "Bitte den Benutzernamen ausfüllen.", http.StatusInternalServerError)
|
||||||
UserName: r.PostFormValue("username"),
|
return
|
||||||
FirstName: r.PostFormValue("first-name"),
|
|
||||||
LastName: r.PostFormValue("last-name"),
|
|
||||||
Role: role,
|
|
||||||
},
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
user.FirstName = r.PostFormValue("first-name")
|
||||||
|
user.LastName = r.PostFormValue("last-name")
|
||||||
|
if len(user.FirstName) == 0 || len(user.LastName) == 0 {
|
||||||
|
http.Error(w, "Bitte den vollständigen Namen ausfüllen.", http.StatusInternalServerError)
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
newPass := r.PostFormValue("password")
|
newPass := r.PostFormValue("password")
|
||||||
newPass2 := r.PostFormValue("password2")
|
newPass2 := r.PostFormValue("password2")
|
||||||
|
|
||||||
if len(userData.UserName) == 0 || len(userData.FirstName) == 0 ||
|
userString, stringLen, ok := checkUserStrings(user)
|
||||||
len(userData.LastName) == 0 {
|
|
||||||
userData.Msg = "Alle Felder mit * müssen ausgefüllt sein."
|
|
||||||
tmpl, err := template.ParseFiles(c.WebDir + "/templates/edit-user.html")
|
|
||||||
tmpl = template.Must(tmpl, err)
|
|
||||||
tmpl.ExecuteTemplate(w, "page-content", userData.Msg)
|
|
||||||
return
|
|
||||||
}
|
|
||||||
|
|
||||||
userString, stringLen, ok := checkUserStrings(userData.User)
|
|
||||||
if !ok {
|
if !ok {
|
||||||
userData.Msg = fmt.Sprint(userString, " ist zu lang. Maximal ",
|
http.Error(w, fmt.Sprint(userString, " ist zu lang. Maximal ", stringLen, " Zeichen erlaubt."), http.StatusBadRequest)
|
||||||
stringLen, " Zeichen erlaubt.")
|
|
||||||
tmpl, err := template.ParseFiles(c.WebDir + "/templates/edit-user.html")
|
|
||||||
tmpl = template.Must(tmpl, err)
|
|
||||||
tmpl.ExecuteTemplate(w, "page-content", userData)
|
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
if id, ok := db.GetID(userData.UserName); ok {
|
if id := db.GetID(user.UserName); id != 0 && id != user.ID {
|
||||||
if id != userData.ID {
|
http.Error(w, user.UserName+" ist bereits vergeben. Bitte anderen Benutzernamen wählen.", http.StatusBadRequest)
|
||||||
userData.Msg = "Benutzername bereits vergeben."
|
|
||||||
userData.UserName = ""
|
|
||||||
tmpl, err := template.ParseFiles(c.WebDir + "/templates/edit-user.html")
|
|
||||||
tmpl = template.Must(tmpl, err)
|
|
||||||
tmpl.ExecuteTemplate(w, "page-content", userData)
|
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if err = db.UpdateUserAttributes(user.ID, user.UserName, user.FirstName, user.LastName, newPass, newPass2, user.Role); err != nil {
|
||||||
|
log.Println("error: user:", user.ID, err)
|
||||||
|
http.Error(w, "Benutzerdaten konnten nicht aktualisiert werden.", http.StatusInternalServerError)
|
||||||
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
if err = db.UpdateUserAttributes(
|
tmpl := template.Must(template.ParseFiles(c.WebDir + "/templates/hub.html"))
|
||||||
userData.ID,
|
if err = tmpl.ExecuteTemplate(w, "page-content", session.Values["role"].(int)); err != nil {
|
||||||
userData.UserName,
|
log.Println(err)
|
||||||
userData.FirstName,
|
http.Error(w, err.Error(), http.StatusInternalServerError)
|
||||||
userData.LastName,
|
return
|
||||||
newPass,
|
|
||||||
newPass2,
|
|
||||||
userData.Role); err != nil {
|
|
||||||
userData.Msg = "Aktualisierung der Benutzerdaten fehlgeschlagen."
|
|
||||||
tmpl, err := template.ParseFiles(c.WebDir + "/templates/edit-user.html")
|
|
||||||
template.Must(tmpl, err).ExecuteTemplate(w, "page-content", userData)
|
|
||||||
}
|
}
|
||||||
|
|
||||||
tmpl, err := template.ParseFiles(c.WebDir + "/templates/hub.html")
|
|
||||||
tmpl = template.Must(tmpl, err)
|
|
||||||
tmpl.ExecuteTemplate(w, "page-content", session.Values["role"].(int))
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -407,6 +387,8 @@ func DeleteUser(c *b.Config, db *b.DB, s *b.CookieStore) http.HandlerFunc {
|
|||||||
return func(w http.ResponseWriter, r *http.Request) {
|
return func(w http.ResponseWriter, r *http.Request) {
|
||||||
session, err := getSession(w, r, c, s)
|
session, err := getSession(w, r, c, s)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
|
log.Println(err)
|
||||||
|
http.Error(w, err.Error(), http.StatusInternalServerError)
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -425,6 +407,10 @@ func DeleteUser(c *b.Config, db *b.DB, s *b.CookieStore) http.HandlerFunc {
|
|||||||
|
|
||||||
tmpl, err := template.ParseFiles(c.WebDir + "/templates/hub.html")
|
tmpl, err := template.ParseFiles(c.WebDir + "/templates/hub.html")
|
||||||
tmpl = template.Must(tmpl, err)
|
tmpl = template.Must(tmpl, err)
|
||||||
tmpl.ExecuteTemplate(w, "page-content", session.Values["role"].(int))
|
if err = tmpl.ExecuteTemplate(w, "page-content", session.Values["role"].(int)); err != nil {
|
||||||
|
log.Println(err)
|
||||||
|
http.Error(w, err.Error(), http.StatusInternalServerError)
|
||||||
|
return
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
2
go.mod
2
go.mod
@ -8,14 +8,12 @@ require (
|
|||||||
firebase.google.com/go/v4 v4.14.1
|
firebase.google.com/go/v4 v4.14.1
|
||||||
git.streifling.com/jason/rss v0.1.3
|
git.streifling.com/jason/rss v0.1.3
|
||||||
github.com/BurntSushi/toml v1.3.2
|
github.com/BurntSushi/toml v1.3.2
|
||||||
github.com/anthonynsimon/bild v0.14.0
|
|
||||||
github.com/chai2010/webp v1.1.1
|
github.com/chai2010/webp v1.1.1
|
||||||
github.com/disintegration/imaging v1.6.2
|
github.com/disintegration/imaging v1.6.2
|
||||||
github.com/go-sql-driver/mysql v1.7.1
|
github.com/go-sql-driver/mysql v1.7.1
|
||||||
github.com/google/uuid v1.6.0
|
github.com/google/uuid v1.6.0
|
||||||
github.com/gorilla/sessions v1.2.2
|
github.com/gorilla/sessions v1.2.2
|
||||||
github.com/microcosm-cc/bluemonday v1.0.26
|
github.com/microcosm-cc/bluemonday v1.0.26
|
||||||
github.com/rwcarlsen/goexif v0.0.0-20190401172101-9e8deecbddbd
|
|
||||||
github.com/yuin/goldmark v1.7.4
|
github.com/yuin/goldmark v1.7.4
|
||||||
golang.org/x/crypto v0.27.0
|
golang.org/x/crypto v0.27.0
|
||||||
golang.org/x/term v0.24.0
|
golang.org/x/term v0.24.0
|
||||||
|
4
go.sum
4
go.sum
@ -24,8 +24,6 @@ github.com/BurntSushi/toml v1.3.2 h1:o7IhLm0Msx3BaB+n3Ag7L8EVlByGnpq14C4YWiu/gL8
|
|||||||
github.com/BurntSushi/toml v1.3.2/go.mod h1:CxXYINrC8qIiEnFrOxCa7Jy5BFHlXnUU2pbicEuybxQ=
|
github.com/BurntSushi/toml v1.3.2/go.mod h1:CxXYINrC8qIiEnFrOxCa7Jy5BFHlXnUU2pbicEuybxQ=
|
||||||
github.com/MicahParks/keyfunc v1.9.0 h1:lhKd5xrFHLNOWrDc4Tyb/Q1AJ4LCzQ48GVJyVIID3+o=
|
github.com/MicahParks/keyfunc v1.9.0 h1:lhKd5xrFHLNOWrDc4Tyb/Q1AJ4LCzQ48GVJyVIID3+o=
|
||||||
github.com/MicahParks/keyfunc v1.9.0/go.mod h1:IdnCilugA0O/99dW+/MkvlyrsX8+L8+x95xuVNtM5jw=
|
github.com/MicahParks/keyfunc v1.9.0/go.mod h1:IdnCilugA0O/99dW+/MkvlyrsX8+L8+x95xuVNtM5jw=
|
||||||
github.com/anthonynsimon/bild v0.14.0 h1:IFRkmKdNdqmexXHfEU7rPlAmdUZ8BDZEGtGHDnGWync=
|
|
||||||
github.com/anthonynsimon/bild v0.14.0/go.mod h1:hcvEAyBjTW69qkKJTfpcDQ83sSZHxwOunsseDfeQhUs=
|
|
||||||
github.com/aymerick/douceur v0.2.0 h1:Mv+mAeH1Q+n9Fr+oyamOlAkUNPWPlA8PPGR0QAaYuPk=
|
github.com/aymerick/douceur v0.2.0 h1:Mv+mAeH1Q+n9Fr+oyamOlAkUNPWPlA8PPGR0QAaYuPk=
|
||||||
github.com/aymerick/douceur v0.2.0/go.mod h1:wlT5vV2O3h55X9m7iVYN0TBM0NH/MmbLnd30/FjWUq4=
|
github.com/aymerick/douceur v0.2.0/go.mod h1:wlT5vV2O3h55X9m7iVYN0TBM0NH/MmbLnd30/FjWUq4=
|
||||||
github.com/census-instrumentation/opencensus-proto v0.2.1/go.mod h1:f6KPmirojxKA12rnyqOA5BBL4O983OfeGPqjHWSTneU=
|
github.com/census-instrumentation/opencensus-proto v0.2.1/go.mod h1:f6KPmirojxKA12rnyqOA5BBL4O983OfeGPqjHWSTneU=
|
||||||
@ -103,8 +101,6 @@ github.com/microcosm-cc/bluemonday v1.0.26/go.mod h1:JyzOCs9gkyQyjs+6h10UEVSe02C
|
|||||||
github.com/pmezard/go-difflib v1.0.0 h1:4DBwDE0NGyQoBHbLQYPwSUPoCMWR5BEzIk/f1lZbAQM=
|
github.com/pmezard/go-difflib v1.0.0 h1:4DBwDE0NGyQoBHbLQYPwSUPoCMWR5BEzIk/f1lZbAQM=
|
||||||
github.com/pmezard/go-difflib v1.0.0/go.mod h1:iKH77koFhYxTK1pcRnkKkqfTogsbg7gZNVY4sRDYZ/4=
|
github.com/pmezard/go-difflib v1.0.0/go.mod h1:iKH77koFhYxTK1pcRnkKkqfTogsbg7gZNVY4sRDYZ/4=
|
||||||
github.com/prometheus/client_model v0.0.0-20190812154241-14fe0d1b01d4/go.mod h1:xMI15A0UPsDsEKsMN9yxemIoYk6Tm2C1GtYGdfGttqA=
|
github.com/prometheus/client_model v0.0.0-20190812154241-14fe0d1b01d4/go.mod h1:xMI15A0UPsDsEKsMN9yxemIoYk6Tm2C1GtYGdfGttqA=
|
||||||
github.com/rwcarlsen/goexif v0.0.0-20190401172101-9e8deecbddbd h1:CmH9+J6ZSsIjUK3dcGsnCnO41eRBOnY12zwkn5qVwgc=
|
|
||||||
github.com/rwcarlsen/goexif v0.0.0-20190401172101-9e8deecbddbd/go.mod h1:hPqNNc0+uJM6H+SuU8sEs5K5IQeKccPqeSjfgcKGgPk=
|
|
||||||
github.com/stretchr/objx v0.1.0/go.mod h1:HFkY916IF+rwdDfMAkV7OtwuqBVzrE8GR6GFx+wExME=
|
github.com/stretchr/objx v0.1.0/go.mod h1:HFkY916IF+rwdDfMAkV7OtwuqBVzrE8GR6GFx+wExME=
|
||||||
github.com/stretchr/objx v0.4.0/go.mod h1:YvHI0jy2hoMjB+UWwv71VJQ9isScKT/TqJzVSSt89Yw=
|
github.com/stretchr/objx v0.4.0/go.mod h1:YvHI0jy2hoMjB+UWwv71VJQ9isScKT/TqJzVSSt89Yw=
|
||||||
github.com/stretchr/objx v0.5.0/go.mod h1:Yh+to48EsGEfYuaHDzXPcE3xhTkx73EhmCGUpEOglKo=
|
github.com/stretchr/objx v0.5.0/go.mod h1:Yh+to48EsGEfYuaHDzXPcE3xhTkx73EhmCGUpEOglKo=
|
||||||
|
@ -49,11 +49,4 @@
|
|||||||
<button class="btn" hx-get="/hub" hx-target="#page-content">Abbrechen</button>
|
<button class="btn" hx-get="/hub" hx-target="#page-content">Abbrechen</button>
|
||||||
</div>
|
</div>
|
||||||
</form>
|
</form>
|
||||||
|
|
||||||
<script>
|
|
||||||
var msg = "{{.Msg}}";
|
|
||||||
if (msg != "") {
|
|
||||||
alert(msg);
|
|
||||||
}
|
|
||||||
</script>
|
|
||||||
{{end}}
|
{{end}}
|
||||||
|
@ -64,6 +64,7 @@
|
|||||||
onSuccess(data);
|
onSuccess(data);
|
||||||
})
|
})
|
||||||
.catch(error => {
|
.catch(error => {
|
||||||
|
htmx.trigger(htmx.find('#notification'), 'htmx:responseError', {xhr: {responseText: error.message}});
|
||||||
onError(error);
|
onError(error);
|
||||||
});
|
});
|
||||||
},
|
},
|
||||||
|
@ -29,11 +29,4 @@
|
|||||||
<input class="action-btn" type="submit" value="Anlegen" hx-post="/user/add-first" hx-target="#page-content" />
|
<input class="action-btn" type="submit" value="Anlegen" hx-post="/user/add-first" hx-target="#page-content" />
|
||||||
</div>
|
</div>
|
||||||
</form>
|
</form>
|
||||||
|
|
||||||
<script>
|
|
||||||
var msg = "{{.Msg}}";
|
|
||||||
if (msg != "") {
|
|
||||||
alert(msg);
|
|
||||||
}
|
|
||||||
</script>
|
|
||||||
{{end}}
|
{{end}}
|
||||||
|
@ -28,6 +28,10 @@
|
|||||||
</header>
|
</header>
|
||||||
|
|
||||||
<main class="mx-4">
|
<main class="mx-4">
|
||||||
|
<div class="hidden bg-slate-950 dark:bg-slate-50 fixed font-bold p-4 right-8 rounded-lg shadow-lg text-slate-100 dark:text-slate-900 top-8 z-50"
|
||||||
|
id="notification">
|
||||||
|
</div>
|
||||||
|
|
||||||
<div id="page-content">
|
<div id="page-content">
|
||||||
{{template "page-content" .}}
|
{{template "page-content" .}}
|
||||||
</div>
|
</div>
|
||||||
@ -35,7 +39,7 @@
|
|||||||
|
|
||||||
<footer class="text-center text-gray-500 my-8">
|
<footer class="text-center text-gray-500 my-8">
|
||||||
<p>© 2024 Jason Streifling. Alle Rechte vorbehalten.</p>
|
<p>© 2024 Jason Streifling. Alle Rechte vorbehalten.</p>
|
||||||
<p>v0.11.1 - <strong>Alpha: Drastische Änderungen und Fehler vorbehalten.</strong></p>
|
<p>v0.12.0 - <strong>Alpha: Drastische Änderungen und Fehler vorbehalten.</strong></p>
|
||||||
</footer>
|
</footer>
|
||||||
|
|
||||||
<script src="https://unpkg.com/htmx.org@2.0.2"></script>
|
<script src="https://unpkg.com/htmx.org@2.0.2"></script>
|
||||||
@ -66,6 +70,16 @@
|
|||||||
});
|
});
|
||||||
});
|
});
|
||||||
</script>
|
</script>
|
||||||
|
<script>
|
||||||
|
htmx.on('htmx:responseError', function (event) {
|
||||||
|
var notification = document.getElementById('notification');
|
||||||
|
notification.innerText = event.detail.xhr.responseText;
|
||||||
|
notification.classList.remove('hidden');
|
||||||
|
setTimeout(function () {
|
||||||
|
notification.classList.add('hidden');
|
||||||
|
}, 5000);
|
||||||
|
});
|
||||||
|
</script>
|
||||||
</body>
|
</body>
|
||||||
|
|
||||||
</html>
|
</html>
|
||||||
|
Reference in New Issue
Block a user