package main import ( "database/sql" "embed" "encoding/json" "fmt" "io/fs" "log" "net/http" "github.com/gorilla/mux" ) //go:embed build/frontend/public var frontendEmbed embed.FS func registerHandlers(r *mux.Router, db *sql.DB) { r.Handle("/api/version", ApiVersion(db)) r.Handle("/api/authentication", ApiAuthentication(db)) // frontend must come last to make sure /api takes precedence frontend, err := fs.Sub(frontendEmbed, "build/frontend/public") if err != nil { log.Fatalf("No embedded frontend: %v.", err) } r.PathPrefix("/").Handler(http.FileServerFS(frontend)) } func ApiVersion(db *sql.DB) http.Handler { return http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) { fmt.Fprint(w, versionTxt) }) } func ApiAuthentication(db *sql.DB) http.Handler { return http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) { var data struct { Username string Password string } dec := json.NewDecoder(r.Body) dec.DisallowUnknownFields() err := dec.Decode(&data) if err != nil { log.Printf("Failed to decode: %v.", err) w.WriteHeader(http.StatusBadRequest) return } if data.Username == "" { log.Print("Got registration request with empty username.") w.WriteHeader(http.StatusBadRequest) return } if data.Password == "" { log.Print("Got registration request with empty password.") w.WriteHeader(http.StatusBadRequest) return } err = Authenticate(db, data.Username, data.Password) if err != nil { log.Printf("Bad password on authentication of user '%s'.", data.Username) w.WriteHeader(http.StatusUnauthorized) return } }) }