package main import ( "log" "net/http" "os" "path" "path/filepath" "strconv" "time" "github.com/go-chi/chi/v5" "github.com/go-chi/chi/v5/middleware" "github.com/google/uuid" "github.com/neonxp/sendsafe/internal/renderer" "github.com/neonxp/sendsafe/internal/storer" ) var workDir, _ = os.Getwd() func main() { s, err := storer.New(path.Join(workDir, "memos.db")) if err != nil { log.Fatal(err) } r := chi.NewRouter() r.Use(middleware.Logger) r.Use(middleware.Recoverer) r.Use(middleware.Compress(9)) tpl, err := renderer.New(path.Join(workDir, "templates")) if err != nil { log.Fatal(err) } r.Get("/", func(rw http.ResponseWriter, _ *http.Request) { csrf := uuid.NewString() http.SetCookie(rw, &http.Cookie{ Name: "csrf", Value: csrf, Expires: time.Now().Add(30 * time.Minute), HttpOnly: true, }) if err := tpl.Render("index.gohtml", renderer.Map{"csrf": csrf}, rw); err != nil { log.Println(err) _ = tpl.Render("error.gohtml", nil, rw) } }) r.Post("/save", func(rw http.ResponseWriter, r *http.Request) { if err := r.ParseForm(); err != nil { log.Println(err) _ = tpl.Render("error.gohtml", nil, rw) return } secret := r.FormValue("secret") days, err := strconv.Atoi(r.FormValue("days")) if err != nil { log.Println(err) _ = tpl.Render("error.gohtml", nil, rw) return } hours, err := strconv.Atoi(r.FormValue("hours")) if err != nil { log.Println(err) _ = tpl.Render("error.gohtml", nil, rw) return } minutes, err := strconv.Atoi(r.FormValue("minutes")) if err != nil { log.Println(err) _ = tpl.Render("error.gohtml", nil, rw) return } pin := r.FormValue("pin") csrf := r.FormValue("csrf") csrfCookie, err := r.Cookie("csrf") if err != nil { log.Println(err) _ = tpl.Render("error.gohtml", nil, rw) return } if csrfCookie.Value != csrf { log.Println(err) _ = tpl.Render("error.gohtml", nil, rw) return } ttl := days*24*60 + hours*60 + minutes id, err := s.Save(secret, pin, ttl) if err != nil { log.Println(err) _ = tpl.Render("error.gohtml", nil, rw) return } if err := tpl.Render("save.gohtml", renderer.Map{"id": id}, rw); err != nil { log.Println(err) _ = tpl.Render("error.gohtml", nil, rw) } }) r.Get("/s/{id}", func(rw http.ResponseWriter, r *http.Request) { id := chi.URLParam(r, "id") if err != nil { log.Println(err) _ = tpl.Render("notfound.gohtml", nil, rw) return } _, err := s.IsEncrypted(id) if err != nil { log.Println(err) _ = tpl.Render("notfound.gohtml", nil, rw) return } if err := tpl.Render("memo.gohtml", renderer.Map{"id": id}, rw); err != nil { log.Println(err) _ = tpl.Render("error.gohtml", nil, rw) } }) r.Get("/api/s/{id}", func(rw http.ResponseWriter, r *http.Request) { id := chi.URLParam(r, "id") secret, err := s.Get(id, "") if err != nil { log.Println(err) _ = tpl.Render("notfoundinline.gohtml", nil, rw) return } if err := tpl.Render("secret.gohtml", renderer.Map{"secret": secret}, rw); err != nil { log.Println(err) _ = tpl.Render("notfoundinline.gohtml", nil, rw) } }) filesDir := http.Dir(filepath.Join(workDir, "public")) r.Get("/*", func(w http.ResponseWriter, r *http.Request) { fs := http.StripPrefix("/", http.FileServer(filesDir)) fs.ServeHTTP(w, r) }) if err := http.ListenAndServe(":3000", r); err != nil { log.Fatal(err) } }