package main import ( "bytes" "fmt" "log" "net/http" "text/template" "time" "github.com/CalebQ42/darkstorm-server/internal/backend" "github.com/CalebQ42/darkstorm-server/internal/blog" ) // //go:embed embed // var editorFS embed.FS const ( loginPage = `
` editorPage = `

Select a blog!

` editorForm = `

` ) func loginPageRequest(w http.ResponseWriter, r *http.Request) { sendContent(w, r, loginPage, "", "") } func trueLoginRequest(w http.ResponseWriter, r *http.Request) { if r.Header.Get("HX-Request") != "true" { sendContent(w, r, "

Bad request

", "", "") return } err := r.ParseForm() if err != nil { sendContent(w, r, "

Bad request

", "", "") return } u, err := back.TryLogin(r.Context(), r.FormValue("username"), r.FormValue("password")) if err != nil { if err == backend.ErrLoginTimeout { sendContent(w, r, fmt.Sprint("

Timed out for", time.Unix(u.Timeout, 0).Sub(time.Now()), "

"), "", "") } else if err == backend.ErrLoginIncorrect { sendContent(w, r, "

Username or password invalid

", "", "") } else { log.Println("error trying to login:", err) sendContent(w, r, "

Server error

", "", "") } return } tok, err := back.GenerateJWT(u.ToReqUser()) if err != nil { log.Println("error trying to generate JWT:", err) sendContent(w, r, "

Server error

", "", "") return } w.Header().Set("Set-Cookie", "blogAuthToken="+tok+"; Secure; Max-Age=43170") // Max-Age is 11.5 hours. JWTs are valid for 12 hours. sendContent(w, r, "

Successful Login

", "", "") } func editorRequest(w http.ResponseWriter, r *http.Request) { if !verifyEditorCookie(r) { editorRedirect(w, r, "/login") return } tmpl, err := template.New("page").Parse(editorPage) if err != nil { log.Println("error parsing editor template:", err) sendContent(w, r, "ERROR", "", "") return } blogs, _ := blogApp.LatestBlogs(r.Context(), 0) buf := new(bytes.Buffer) err = tmpl.Execute(buf, blogs) if err != nil { log.Println("error executing editor page template:", err) sendContent(w, r, "ERROR", "", "") return } sendContent(w, r, buf.String(), "", "") } func editorEdit(w http.ResponseWriter, r *http.Request) { if !verifyEditorCookie(r) { editorRedirect(w, r, "/login") return } tmpl, err := template.New("editor").Parse(editorForm) if err != nil { log.Println("error parsing editor template:", err) sendContent(w, r, "ERROR", "", "") return } var bl *blog.Blog blogID := r.URL.Query().Get("blog") if blogID == "" { sendContent(w, r, "

Select a blog!

", "", "") return } if blogID == "new" { bl = &blog.Blog{} } else { bl, err = blogApp.Blog(r.Context(), r.URL.Query().Get("blog")) if err != nil { log.Println("error getting blog for editor:", err) sendContent(w, r, "ERROR", "", "") return } } buf := new(bytes.Buffer) err = tmpl.Execute(buf, bl) if err != nil { log.Println("error executing editor template:", err) sendContent(w, r, "ERROR", "", "") return } sendContent(w, r, buf.String(), "", "") } func verifyEditorCookie(r *http.Request) bool { authCookie, err := r.Cookie("blogAuthToken") if err != nil { if err != http.ErrNoCookie { log.Println("error getting auth cookie:", err) } return false } _, err = back.VerifyUser(r.Context(), authCookie.Value) if err != nil { if err != backend.ErrTokenUnauthorized { log.Println("error authorizing JWT token:", err) } return false } return true } func editorRedirect(w http.ResponseWriter, r *http.Request, path string) { if r.Header.Get("HX-Request") == "true" { w.Header().Set("HX-Location", `{"path": "`+path+`", "target":"#content"}`) return } http.Redirect(w, r, "https://darkstorm.tech"+path, http.StatusFound) }