package user import ( "bytes" "embed" "fmt" "github.com/go-chi/chi/v5" "github.com/go-chi/jwtauth/v5" "github.com/unrolled/render" gomail "gopkg.in/mail.v2" "io" "net/http" "time" ) // content holds our static web server content. //go:embed templates/* var webserver embed.FS var ren *render.Render var uc UserClient var tokenAuth *jwtauth.JWTAuth var d *gomail.Dialer type UserConfig struct { RegisterMail *gomail.Message URLValidationToken string } var userconfig UserConfig func NewUserConfig() UserConfig { uc := UserConfig{} m := gomail.NewMessage() m.SetHeader("From", "test@keks.cloud") m.SetHeader("To", "to@example.com") m.SetHeader("Subject", "Activate your Account") uc.RegisterMail = m uc.URLValidationToken = "http://localhost/validate/%s" return uc } func Register(router chi.Router, token *jwtauth.JWTAuth, userClient UserClient, dialer *gomail.Dialer, config UserConfig) { uc = userClient userconfig = config ren = render.New(render.Options{ //Layout: "layout", FileSystem: &render.EmbedFileSystem{ FS: webserver, }, }) router.Get("/login", loginForm) router.Post("/login", login) router.Get("/register", registerForm) router.Post("/register", register) router.Get("/logout", logout) tokenAuth = token d = dialer router.Group(func(r chi.Router) { r.Use(jwtauth.Verifier(tokenAuth)) r.Get("/me", func(w http.ResponseWriter, r *http.Request) { _, claims, _ := jwtauth.FromContext(r.Context()) if val, ok := claims["username"]; ok { w.Write([]byte(fmt.Sprintf("hi %v", val))) } else { w.Write([]byte("Du bist nicht eingeloggt")) } }) }) } func loginForm(w http.ResponseWriter, r *http.Request) { ren.HTML(w, http.StatusOK, "login", nil) } func registerForm(w http.ResponseWriter, r *http.Request) { ren.HTML(w, http.StatusOK, "register", nil) } func login(w http.ResponseWriter, r *http.Request) { r.ParseForm() res, err := uc.login(r.FormValue("username"), r.FormValue("password"), false) if err != nil { w.Write([]byte(err.Error())) return } if res { _, tokenstring, err := tokenAuth.Encode(map[string]interface{}{"username": r.FormValue("username")}) if err != nil { panic(err) } expiration := time.Now().Add(365 * 24 * time.Hour) cookie := http.Cookie{Name: "jwt",Value:tokenstring,Expires:expiration} http.SetCookie(w, &cookie) w.Write([]byte("Login ok")) } else { w.Write([]byte("Login failed")) } } func logout(w http.ResponseWriter, r *http.Request) { cookie := http.Cookie{ Name: "jwt", Value: "", } http.SetCookie(w, &cookie) w.Write([]byte("Du wurdest ausgeloggt")) } func register(w http.ResponseWriter, r *http.Request) { r.ParseForm() res, err := uc.register(r.FormValue("username"), r.FormValue("password"), r.FormValue("email")) if err != nil || res == false { w.Write([]byte("Registration Failed")) return } rw := &LayoutMiddlewareResponseWriter{ ResponseWriter: w, buf: &bytes.Buffer{}, } token, err := uc.getMailValidationToken(r.FormValue("email"), true) if err != nil { panic(err) } ren.HTML(rw, http.StatusOK, "token", map[string]string{"username": r.FormValue("username"), "url": fmt.Sprintf(userconfig.URLValidationToken, token)}) content, err := io.ReadAll(rw.buf) if err != nil { panic(err) } mail := *userconfig.RegisterMail mail.SetBody("text/html", string(content)) if err := d.DialAndSend(&mail); err != nil { fmt.Println(err) panic(err) } } type LayoutMiddlewareResponseWriter struct { http.ResponseWriter buf *bytes.Buffer } func (myrw *LayoutMiddlewareResponseWriter) Write(p []byte) (int, error) { return myrw.buf.Write(p) }