package service import ( "crypto/rand" "database/sql" "log" "net/http" "net/mail" "strings" "me-fit/template" "me-fit/template/auth" "github.com/google/uuid" "golang.org/x/crypto/argon2" ) func SignInPage(w http.ResponseWriter, r *http.Request) { signIn := auth.SignInOrUp(true) template.Layout(signIn).Render(r.Context(), w) } func SignUpPage(w http.ResponseWriter, r *http.Request) { signIn := auth.SignInOrUp(false) template.Layout(signIn).Render(r.Context(), w) } func SignUp(db *sql.DB) http.HandlerFunc { return func(w http.ResponseWriter, r *http.Request) { } } // var ( // metricsAuthSignUp = promauto.NewCounterVec( // prometheus.CounterOpts{ // Name: "mefit_api_auth_signup_total", // Help: "The total number of auth signup api requests processed", // }, // []string{"result"}, // ) // // metricsError = promauto.NewCounterVec( // prometheus.CounterOpts{ // Name: "mefit_api_error_total", // Help: "The total number of errors", // }, // []string{"result"}, // ) // // // metricsAuthSignIn = promauto.NewCounterVec( // // prometheus.CounterOpts{ // // Name: "mefit_api_auth_signin_total", // // }, // // []string{"result"}, // // ) // // privateKey = func() *ecdsa.PrivateKey { // keyBase64 := os.Getenv("PRIVATE_KEY") // if keyBase64 == "" { // log.Fatal("PRIVATE_KEY not defined") // } // keyData, err := base64.StdEncoding.DecodeString(keyBase64) // if err != nil { // log.Fatalf("Could not decode private key: %v", err) // } // key, err := x509.ParseECPrivateKey(keyData) // if err != nil { // log.Fatalf("Could not parse private key: %v", err) // } // log.Println("Successfully imported private key") // return key // }() // ) func PostSignup(db *sql.DB) http.HandlerFunc { return func(w http.ResponseWriter, r *http.Request) { var email = r.FormValue("email") var password = r.FormValue("password") _, err := mail.ParseAddress(email) if err != nil { http.Error(w, "Invalid email", http.StatusBadRequest) return } if len(password) < 8 || !strings.ContainsAny(password, "0123456789") || !strings.ContainsAny(password, "ABCDEFGHIJKLMNOPQRSTUVWXYZ") || !strings.ContainsAny(password, "abcdefghijklmnopqrstuvwxyz") || !strings.ContainsAny(password, "!@#$%^&*()_+-=[]{}\\|;:'\",.<>/?") { http.Error(w, "Password needs to be 8 characters long, contain at least one number, one special, one uppercase and one lowercase character", http.StatusBadRequest) return } user_uuid, err := uuid.NewRandom() if err != nil { http.Error(w, err.Error(), http.StatusInternalServerError) log.Printf("Could not generate UUID: %v", err) return } salt := make([]byte, 16) rand.Read(salt) hash := argon2.IDKey([]byte(password), salt, 1, 64*1024, 1, 16) _, err = db.Exec("INSERT INTO user (user_uuid, email, email_verified, is_admin, password, salt, created_at) VALUES (?, ?, FALSE, FALSE, ?, ?, datetime())", user_uuid, email, hash, salt) if err != nil { if strings.Contains(err.Error(), "email") { http.Error(w, "Email already exists", http.StatusBadRequest) return } http.Error(w, err.Error(), http.StatusInternalServerError) log.Printf("Could not insert user: %v", err) return } w.WriteHeader(http.StatusOK) // w.Write([]byte(token)) } }