From ae014d195013e2530390322896bd38a2d1ff0b70 Mon Sep 17 00:00:00 2001 From: nikurasu Date: Mon, 16 Oct 2023 21:28:25 +0200 Subject: [PATCH] Initial Commit :3 --- .gitignore | 4 + .../images/production/backend/Dockerfile | 11 ++ .../stacks/production/docker-compose.yml | 9 ++ src/.env.template | 3 + src/app/controller/attendies_controller.go | 45 +++++++ src/app/controller/events_controller.go | 110 ++++++++++++++++++ src/app/controller/ping_controller.go | 9 ++ src/app/routes/private_routes.go | 16 +++ src/app/routes/public_routes.go | 12 ++ src/app/service/db_event.go | 61 ++++++++++ .../util/get_attendies_from_pretix_json.go | 46 ++++++++ src/app/util/validate.go | 24 ++++ src/app/views/error.html | 11 ++ src/app/views/index.html | 17 +++ src/app/views/table.html | 36 ++++++ src/config/database.go | 22 ++++ src/config/environment.go | 22 ++++ src/config/fiber.go | 18 +++ src/config/http.go | 9 ++ src/config/validator.go | 38 ++++++ src/entities/attendies.go | 9 ++ src/entities/db_event.go | 21 ++++ src/entities/environment.go | 8 ++ src/entities/pretix.go | 22 ++++ src/go.mod | 44 +++++++ src/main.go | 34 ++++++ 26 files changed, 661 insertions(+) create mode 100644 .gitignore create mode 100644 dev/docker/images/production/backend/Dockerfile create mode 100644 dev/docker/stacks/production/docker-compose.yml create mode 100644 src/.env.template create mode 100644 src/app/controller/attendies_controller.go create mode 100644 src/app/controller/events_controller.go create mode 100644 src/app/controller/ping_controller.go create mode 100644 src/app/routes/private_routes.go create mode 100644 src/app/routes/public_routes.go create mode 100644 src/app/service/db_event.go create mode 100644 src/app/util/get_attendies_from_pretix_json.go create mode 100644 src/app/util/validate.go create mode 100644 src/app/views/error.html create mode 100644 src/app/views/index.html create mode 100644 src/app/views/table.html create mode 100644 src/config/database.go create mode 100644 src/config/environment.go create mode 100644 src/config/fiber.go create mode 100644 src/config/http.go create mode 100644 src/config/validator.go create mode 100644 src/entities/attendies.go create mode 100644 src/entities/db_event.go create mode 100644 src/entities/environment.go create mode 100644 src/entities/pretix.go create mode 100644 src/go.mod create mode 100644 src/main.go diff --git a/.gitignore b/.gitignore new file mode 100644 index 0000000..a6dc356 --- /dev/null +++ b/.gitignore @@ -0,0 +1,4 @@ +go.sum +.env +pretix-proxy +main.db \ No newline at end of file diff --git a/dev/docker/images/production/backend/Dockerfile b/dev/docker/images/production/backend/Dockerfile new file mode 100644 index 0000000..11ebf9e --- /dev/null +++ b/dev/docker/images/production/backend/Dockerfile @@ -0,0 +1,11 @@ +FROM golang:alpine3.17 AS build +WORKDIR /build +COPY ./src ./src +WORKDIR /build/src +RUN ls +RUN go get . +RUN go build -o /build/pretix-proxy + +FROM alpine:3.17 AS final +COPY --from=build /build/pretix-proxy /bin/pretix-proxy +CMD pretix-proxy \ No newline at end of file diff --git a/dev/docker/stacks/production/docker-compose.yml b/dev/docker/stacks/production/docker-compose.yml new file mode 100644 index 0000000..b8f35c4 --- /dev/null +++ b/dev/docker/stacks/production/docker-compose.yml @@ -0,0 +1,9 @@ +version: '3' +services: + static-hoster: + images: dev.cat-enby.club/nikurasu/pretix-proxy:latest + environment: + - DOMAIN="reg.ulmer-furs.de" + - API_KEY="" + ports: + - 3000:3000 \ No newline at end of file diff --git a/src/.env.template b/src/.env.template new file mode 100644 index 0000000..8797f42 --- /dev/null +++ b/src/.env.template @@ -0,0 +1,3 @@ +DOMAIN="reg.ulmer-furs.de" +API_KEY="" +DEBUG="true" \ No newline at end of file diff --git a/src/app/controller/attendies_controller.go b/src/app/controller/attendies_controller.go new file mode 100644 index 0000000..d933d54 --- /dev/null +++ b/src/app/controller/attendies_controller.go @@ -0,0 +1,45 @@ +package controller + +import ( + "encoding/json" + "fmt" + "io" + "net/http" + + "github.com/gofiber/fiber/v2" + "ulmer-furs.de/pretix-proxy/v2/app/service" + "ulmer-furs.de/pretix-proxy/v2/app/util" + "ulmer-furs.de/pretix-proxy/v2/config" + "ulmer-furs.de/pretix-proxy/v2/entities" +) + +// @Description Get the attendies of an event by the name +func GetAttendiesByEvent(c *fiber.Ctx) error { + name := c.Params("name") + event, err := service.Get_db_event_by_name(name) + if err != nil { + return c.Status(404).SendString(err.Error()) + } + req, err := http.NewRequest("GET", fmt.Sprintf("https://%s/api/v1/organizers/%s/events/%s/orders", config.Env.Domain, event.Organizer, event.Event), nil) + if err != nil { + return c.Status(500).SendString("Internal Server Error") + } + req.Header.Add("Authorization", fmt.Sprintf("Token %s", config.Env.Domain)) + resp, err := config.Client.Do(req) + if err != nil { + return c.Status(500).SendString("Internal Server Error") + } + respbody, err := io.ReadAll(resp.Body) + defer resp.Body.Close() + if err != nil { + return c.Status(500).SendString("Internal Server Error") + } + var unmarshaled_resp entities.Pretix_Event + if err := json.Unmarshal(respbody, &unmarshaled_resp); err != nil { + return c.Status(500).SendString("Internal Server Error") + } + + attendiesAtEvent := util.GetAttendiesFromPretixJson(unmarshaled_resp, event) + c.JSON(attendiesAtEvent) + return c.SendStatus(200) +} diff --git a/src/app/controller/events_controller.go b/src/app/controller/events_controller.go new file mode 100644 index 0000000..ce69001 --- /dev/null +++ b/src/app/controller/events_controller.go @@ -0,0 +1,110 @@ +package controller + +import ( + "strconv" + + "github.com/gofiber/fiber/v2" + "ulmer-furs.de/pretix-proxy/v2/app/service" + "ulmer-furs.de/pretix-proxy/v2/app/util" + "ulmer-furs.de/pretix-proxy/v2/entities" +) + +func ReturnEventsTableView(c *fiber.Ctx) error { + events, err := service.Get_all_db_event() + if err != nil { + return c.Status(500).Render("app/index/index", fiber.Map{ + "Error": err.Error(), + }) + } + return c.Render("app/views/index", fiber.Map{ + "Title": "Ulmer Furs Events", + "Events": events, + "Count": len(events), + }) +} + +func ReturnAllEvents(c *fiber.Ctx) error { + events, err := service.Get_all_db_event() + if err != nil { + return c.Status(500).SendString("Internal Server Error") + } + c.JSON(events) + return c.SendStatus(200) +} + +func ReturnEventById(c *fiber.Ctx) error { + id := c.Params("id") + id_int, err := strconv.Atoi(id) + if err != nil { + return c.Status(400).SendString("Bad Request") + } + event, err := service.Get_db_event_by_id(id_int) + if err != nil { + return c.Status(404).SendString(err.Error()) + } + c.JSON(event) + return c.SendStatus(200) +} + +func DeleteEventById(c *fiber.Ctx) error { + id := c.Params("id") + id_int, err := strconv.Atoi(id) + if err != nil { + return c.Status(400).SendString("Bad Request") + } + if _, err := service.Get_db_event_by_id(id_int); err != nil { + return &fiber.Error{ + Code: fiber.ErrNotFound.Code, + Message: "Event not found", + } + } + if err := service.Delete_db_event_by_id(id_int); err != nil { + return c.Status(404).SendString(err.Error()) + } + return c.SendStatus(200) +} + +func CreateEvent(c *fiber.Ctx) error { + event := new(entities.Db_Event) + if err := c.BodyParser(event); err != nil { + return c.Status(fiber.ErrBadRequest.Code).SendString("Bad Request") + } + event.EnforceRequired = true + + if err, errMsg := util.Validate(event); err { + return &fiber.Error{ + Code: fiber.ErrBadRequest.Code, + Message: errMsg, + } + } + if err := service.Create_new_db_event(*event); err != nil { + return c.Status(fiber.ErrInternalServerError.Code).SendString(err.Error()) + } + return c.SendStatus(fiber.StatusOK) +} + +func UpdateEventById(c *fiber.Ctx) error { + event := new(entities.Db_Event) + id := c.Params("id") + id_int, parseErr := strconv.Atoi(id) + if err := c.BodyParser(event); err != nil || parseErr != nil { + return c.Status(400).SendString("Bad Request") + } + if err, errMsg := util.Validate(event); err { + return &fiber.Error{ + Code: fiber.ErrBadRequest.Code, + Message: errMsg, + } + } + if _, err := service.Get_db_event_by_id(id_int); err != nil { + return &fiber.Error{ + Code: fiber.ErrNotFound.Code, + Message: "Event not found", + } + } + event.ID = uint(id_int) + if err := service.Update_db_event(*event); err != nil { + return c.Status(500).SendString(err.Error()) + } + return c.SendStatus(200) +} diff --git a/src/app/controller/ping_controller.go b/src/app/controller/ping_controller.go new file mode 100644 index 0000000..80faef2 --- /dev/null +++ b/src/app/controller/ping_controller.go @@ -0,0 +1,9 @@ +package controller + +import ( + "github.com/gofiber/fiber/v2" +) + +func Ping(c *fiber.Ctx) error { + return c.SendString("Pong") +} diff --git a/src/app/routes/private_routes.go b/src/app/routes/private_routes.go new file mode 100644 index 0000000..a0c6051 --- /dev/null +++ b/src/app/routes/private_routes.go @@ -0,0 +1,16 @@ +package routes + +import ( + "github.com/gofiber/fiber/v2" + "ulmer-furs.de/pretix-proxy/v2/app/controller" +) + +func PrivateRoutes(app *fiber.App) { + apiv1 := app.Group("/api/v1") + //app.Get("/events", controller.ReturnEventsTableView) + apiv1.Get("/event", controller.ReturnAllEvents) + apiv1.Get("/event/:id", controller.ReturnEventById) + apiv1.Delete("/event/:id", controller.DeleteEventById) + apiv1.Put("/event/:id", controller.UpdateEventById) + apiv1.Put("/event", controller.CreateEvent) +} diff --git a/src/app/routes/public_routes.go b/src/app/routes/public_routes.go new file mode 100644 index 0000000..7c71ea5 --- /dev/null +++ b/src/app/routes/public_routes.go @@ -0,0 +1,12 @@ +package routes + +import ( + "github.com/gofiber/fiber/v2" + "ulmer-furs.de/pretix-proxy/v2/app/controller" +) + +func PublicRoutes(app *fiber.App) { + apiv1 := app.Group("/api/v1") + apiv1.Get("/ping", controller.Ping) + apiv1.Get("/attendies/:name", controller.GetAttendiesByEvent) +} diff --git a/src/app/service/db_event.go b/src/app/service/db_event.go new file mode 100644 index 0000000..ec014ed --- /dev/null +++ b/src/app/service/db_event.go @@ -0,0 +1,61 @@ +package service + +import ( + "errors" + + "gorm.io/gorm" + "ulmer-furs.de/pretix-proxy/v2/config" + "ulmer-furs.de/pretix-proxy/v2/entities" +) + +func Get_db_event_by_id(id int) (entities.Db_Event, error) { + var db_event entities.Db_Event + result := config.Database.Find(&db_event, id) + if result.RowsAffected == 0 { + return db_event, errors.New("event not found") + } + return db_event, nil +} + +func Get_db_event_by_name(name string) (entities.Db_Event, error) { + var db_event entities.Db_Event + result := config.Database.First(&db_event, "name = ?", name) + if result.RowsAffected == 0 { + return db_event, errors.New("event not found") + } + return db_event, nil +} + +func Get_all_db_event() ([]entities.Db_Event, error) { + var db_events []entities.Db_Event + result := config.Database.Find(&db_events) + if errors.Is(result.Error, gorm.ErrRecordNotFound) { + return db_events, errors.New("events not found") + } + return db_events, nil + +} + +func Create_new_db_event(event entities.Db_Event) error { + result := config.Database.Create(&event) + if result.Error != nil { + return result.Error + } + return nil +} + +func Update_db_event(event entities.Db_Event) error { + result := config.Database.Save(event) + if result.Error != nil { + return result.Error + } + return nil +} + +func Delete_db_event_by_id(id int) error { + result := config.Database.Delete(&entities.Db_Event{}, id) + if result.Error != nil { + return result.Error + } + return nil +} diff --git a/src/app/util/get_attendies_from_pretix_json.go b/src/app/util/get_attendies_from_pretix_json.go new file mode 100644 index 0000000..9282bf2 --- /dev/null +++ b/src/app/util/get_attendies_from_pretix_json.go @@ -0,0 +1,46 @@ +package util + +import ( + "golang.org/x/exp/slices" + "ulmer-furs.de/pretix-proxy/v2/entities" +) + +func GetAttendiesFromPretixJson(pretixEvent entities.Pretix_Event, event entities.Db_Event) entities.Attendies { + var attendies entities.Attendies + var name string + + for _, order := range pretixEvent.Results { + indexParticipation := slices.IndexFunc(order.Positions, func(p entities.Pretix_Position) bool { return p.Item == event.ItemIdParticipation }) + indexBadge := slices.IndexFunc(order.Positions, func(p entities.Pretix_Position) bool { return p.Item == event.ItemIdBadge }) + indexRestaurant := slices.IndexFunc(order.Positions, func(p entities.Pretix_Position) bool { return p.Item == event.ItemIdRestaurant }) + // Get the Name of the Attendie. We take the Name from the Badge, if none Badge ordered == anonymous + if indexBadge != -1 { + indexName := slices.IndexFunc(order.Positions[indexBadge].Answers, func(a entities.Pretix_Answer) bool { return a.QuestionsIdentififer == event.QuestionIdName }) + name = order.Positions[indexBadge].Answers[indexName].Answer + } else { + name = "Anonymous" + } + + indexRole := slices.IndexFunc(order.Positions[indexParticipation].Answers, func(a entities.Pretix_Answer) bool { return a.QuestionsIdentififer == event.QuestionIdRole }) + role := order.Positions[indexParticipation].Answers[indexRole].OptionIdentifiers + + if slices.Contains(role, event.OptionIdSuiter) { + attendies.Suiter = append(attendies.Suiter, name) + } else if slices.Contains(role, event.OptionIdSpotter) { + attendies.Spotter = append(attendies.Spotter, name) + } else if slices.Contains(role, event.OptionIdPhotograph) { + attendies.Photographers = append(attendies.Photographers, name) + } else if slices.Contains(role, event.OptionIdGuest) { + attendies.Guests = append(attendies.Guests, name) + } else if slices.Contains(role, event.OptionIdSpecialAnimal) { + attendies.Suiter = append(attendies.Suiter, name) + attendies.Photographers = append(attendies.Photographers, name) + } + + if indexRestaurant != -1 { + attendies.Restaurant = append(attendies.Restaurant, name) + } + } + + return attendies +} diff --git a/src/app/util/validate.go b/src/app/util/validate.go new file mode 100644 index 0000000..4fc5d6e --- /dev/null +++ b/src/app/util/validate.go @@ -0,0 +1,24 @@ +package util + +import ( + "fmt" + "strings" + + "ulmer-furs.de/pretix-proxy/v2/config" +) + +func Validate(data interface{}) (bool, string) { + if errs := config.Validator.Validate(data); len(errs) > 0 && errs[0].Error { + errMsgs := make([]string, 0) + for _, err := range errs { + errMsgs = append(errMsgs, fmt.Sprintf( + "[%s]: '%v' | Needs to implement '%s'", + err.FailedField, + err.Value, + err.Tag, + )) + return true, strings.Join(errMsgs, " and ") + } + } + return false, "" +} diff --git a/src/app/views/error.html b/src/app/views/error.html new file mode 100644 index 0000000..88d98c4 --- /dev/null +++ b/src/app/views/error.html @@ -0,0 +1,11 @@ + + + + + + Error: {{.Error}} + + +

{{.Error}}

+ + \ No newline at end of file diff --git a/src/app/views/index.html b/src/app/views/index.html new file mode 100644 index 0000000..2121800 --- /dev/null +++ b/src/app/views/index.html @@ -0,0 +1,17 @@ + + + + + + {{.Title}} + + +

{{.Title}}

+

Events count: {{.Count}}

+ + {{template "table" .}} + + \ No newline at end of file diff --git a/src/app/views/table.html b/src/app/views/table.html new file mode 100644 index 0000000..a57dce2 --- /dev/null +++ b/src/app/views/table.html @@ -0,0 +1,36 @@ +{{define "table"}} + + + + + + + + + + + + + + + + + {{range .Events}} + + + + + + + + + + + + + + + + {{end}} +
NameOrganizerEventItemIdBadgeItemIdRestaurantItemIdParticipationQuestionIdRoleQuestionIdNameOptionIdSuiterOptionIdGuestOptionIdSpotterOptionIdPhotographOptionIdSpecialAnimal
{{.Name}}{{.Organizer}}{{.Event}}{{.ItemIdBadge}}{{.ItemIdRestaurant}}{{.ItemIdParticipation}}{{.QuestionIdRole}}{{.QuestionIdName}}{{.OptionIdSuiter}}{{.OptionIdGuest}}{{.OptionIdSpotter}}{{.OptionIdPhotograph}}{{.OptionIdSpecialAnimal}}
+{{end}} \ No newline at end of file diff --git a/src/config/database.go b/src/config/database.go new file mode 100644 index 0000000..901271e --- /dev/null +++ b/src/config/database.go @@ -0,0 +1,22 @@ +package config + +import ( + "gorm.io/driver/sqlite" + "gorm.io/gorm" + "ulmer-furs.de/pretix-proxy/v2/entities" +) + +var Database *gorm.DB + +func Connect() error { + var err error + Database, err = gorm.Open(sqlite.Open(Env.DatabasePath), &gorm.Config{}) + + if err != nil { + panic(err) + } + + Database.AutoMigrate(&entities.Db_Event{}) + + return nil +} diff --git a/src/config/environment.go b/src/config/environment.go new file mode 100644 index 0000000..24bf85d --- /dev/null +++ b/src/config/environment.go @@ -0,0 +1,22 @@ +package config + +import ( + "log" + + "github.com/caarlos0/env" + "github.com/joho/godotenv" + "ulmer-furs.de/pretix-proxy/v2/entities" +) + +var Env entities.Environment + +func LoadEnv() { + err := godotenv.Load() + if err != nil { + log.Fatalf("unable to load .env file: %e", err) + } + err = env.Parse(&Env) + if err != nil { + log.Fatalf("unable to parse ennvironment variables: %e", err) + } +} diff --git a/src/config/fiber.go b/src/config/fiber.go new file mode 100644 index 0000000..0766314 --- /dev/null +++ b/src/config/fiber.go @@ -0,0 +1,18 @@ +package config + +import ( + "embed" + "net/http" + + "github.com/gofiber/fiber/v2" + "github.com/gofiber/template/html/v2" +) + +var App *fiber.App + +func SetupFiber(viewFS embed.FS) { + engine := html.NewFileSystem(http.FS(viewFS), ".html") + App = fiber.New(fiber.Config{ + Views: engine, + }) +} diff --git a/src/config/http.go b/src/config/http.go new file mode 100644 index 0000000..0f65103 --- /dev/null +++ b/src/config/http.go @@ -0,0 +1,9 @@ +package config + +import "net/http" + +var Client *http.Client + +func Create() { + Client = &http.Client{} +} diff --git a/src/config/validator.go b/src/config/validator.go new file mode 100644 index 0000000..5c6a946 --- /dev/null +++ b/src/config/validator.go @@ -0,0 +1,38 @@ +package config + +import "github.com/go-playground/validator/v10" + +type XValidator struct { + validator *validator.Validate +} + +type ErrorResponse struct { + Error bool + FailedField string + Tag string + Value interface{} +} + +var Validator *XValidator + +func SetupValidator() { + Validator = &XValidator{ + validator: validator.New(), + } +} + +func (v XValidator) Validate(data interface{}) []ErrorResponse { + validationErrors := []ErrorResponse{} + errs := Validator.validator.Struct(data) + if errs != nil { + for _, err := range errs.(validator.ValidationErrors) { + var elem ErrorResponse + elem.FailedField = err.Field() + elem.Tag = err.Tag() + elem.Value = err.Value() + elem.Error = true + validationErrors = append(validationErrors, elem) + } + } + return validationErrors +} diff --git a/src/entities/attendies.go b/src/entities/attendies.go new file mode 100644 index 0000000..8151e47 --- /dev/null +++ b/src/entities/attendies.go @@ -0,0 +1,9 @@ +package entities + +type Attendies struct { + Suiter []string + Spotter []string + Photographers []string + Guests []string + Restaurant []string +} diff --git a/src/entities/db_event.go b/src/entities/db_event.go new file mode 100644 index 0000000..e0c9509 --- /dev/null +++ b/src/entities/db_event.go @@ -0,0 +1,21 @@ +package entities + +import "gorm.io/gorm" + +type Db_Event struct { + gorm.Model + Name string `gorm:"column:name;unique;not null" validate:"required_if=EnforceRequired true"` + Organizer string `gorm:"column:organizer;not null" validate:"required_if=EnforceRequired true"` + Event string `gorm:"column:event;not null" validate:"required_if=EnforceRequired true"` + ItemIdBadge int `gorm:"column:item_id_badge;not null" validate:"required_if=EnforceRequired true"` + ItemIdRestaurant int `gorm:"column:item_id_restaurant;not null" validate:"required_if=EnforceRequired true"` + ItemIdParticipation int `gorm:"column:item_id_participation;not null" validate:"required_if=EnforceRequired true"` + QuestionIdRole string `gorm:"column:question_id_role;not null" validate:"required_if=EnforceRequired true"` + QuestionIdName string `gorm:"column:question_id_name;not null" validate:"required_if=EnforceRequired true"` + OptionIdSuiter string `gorm:"column:option_id_suiter;not null" validate:"required_if=EnforceRequired true"` + OptionIdGuest string `gorm:"column:option_id_guest;not null" validate:"required_if=EnforceRequired true"` + OptionIdSpotter string `gorm:"column:option_id_spotter;not null" validate:"required_if=EnforceRequired true"` + OptionIdPhotograph string `gorm:"column:option_id_photograph;not null" validate:"required_if=EnforceRequired true"` + OptionIdSpecialAnimal string `gorm:"column:option_id_special_animal;not null" validate:"required_if=EnforceRequired true"` + EnforceRequired bool `gorm:"-"` +} diff --git a/src/entities/environment.go b/src/entities/environment.go new file mode 100644 index 0000000..1945ffd --- /dev/null +++ b/src/entities/environment.go @@ -0,0 +1,8 @@ +package entities + +type Environment struct { + Domain string `env:"DOMAIN,required"` + ApiKey string `env:"API_KEY,required"` + DatabasePath string `env:"DATABASE_PATH,required"` + Debug bool `env:"DEBUG"` +} diff --git a/src/entities/pretix.go b/src/entities/pretix.go new file mode 100644 index 0000000..686fea7 --- /dev/null +++ b/src/entities/pretix.go @@ -0,0 +1,22 @@ +package entities + +type Pretix_Event struct { + Count int `json:"count"` + Results []Pretix_Result `json:"results"` +} + +type Pretix_Result struct { + Positions []Pretix_Position `json:"positions"` +} + +type Pretix_Position struct { + Item int `json:"item"` + AttendieName string `json:"attendee_name"` + Answers []Pretix_Answer `json:"answers"` +} + +type Pretix_Answer struct { + QuestionsIdentififer string `json:"question_identifier"` + Answer string `json:"answer"` + OptionIdentifiers []string `json:"option_identifiers"` +} diff --git a/src/go.mod b/src/go.mod new file mode 100644 index 0000000..0bcbd6e --- /dev/null +++ b/src/go.mod @@ -0,0 +1,44 @@ +module ulmer-furs.de/pretix-proxy/v2 + +go 1.19 + +require ( + github.com/go-playground/validator/v10 v10.15.4 + github.com/gofiber/fiber/v2 v2.48.0 + github.com/joho/godotenv v1.5.1 + gorm.io/driver/sqlite v1.5.3 + gorm.io/gorm v1.25.4 +) + +require ( + github.com/gabriel-vasile/mimetype v1.4.2 // indirect + github.com/go-playground/locales v0.14.1 // indirect + github.com/go-playground/universal-translator v0.18.1 // indirect + github.com/leodido/go-urn v1.2.4 // indirect + golang.org/x/crypto v0.7.0 // indirect + golang.org/x/net v0.8.0 // indirect + golang.org/x/text v0.8.0 // indirect +) + +require ( + github.com/andybalholm/brotli v1.0.5 // indirect + github.com/caarlos0/env v3.5.0+incompatible + github.com/gofiber/template v1.8.2 // indirect + github.com/gofiber/template/html/v2 v2.0.5 + github.com/gofiber/utils v1.1.0 // indirect + github.com/google/uuid v1.3.0 // indirect + github.com/jinzhu/inflection v1.0.0 // indirect + github.com/jinzhu/now v1.1.5 // indirect + github.com/klauspost/compress v1.16.3 // indirect + github.com/mattn/go-colorable v0.1.13 // indirect + github.com/mattn/go-isatty v0.0.19 // indirect + github.com/mattn/go-runewidth v0.0.14 // indirect + github.com/mattn/go-sqlite3 v1.14.17 // indirect + github.com/rivo/uniseg v0.2.0 // indirect + github.com/stretchr/testify v1.8.4 // indirect + github.com/valyala/bytebufferpool v1.0.0 // indirect + github.com/valyala/fasthttp v1.48.0 // indirect + github.com/valyala/tcplisten v1.0.0 // indirect + golang.org/x/exp v0.0.0-20230817173708-d852ddb80c63 + golang.org/x/sys v0.11.0 // indirect +) diff --git a/src/main.go b/src/main.go new file mode 100644 index 0000000..157e19b --- /dev/null +++ b/src/main.go @@ -0,0 +1,34 @@ +package main + +import ( + "embed" + "log" + + "github.com/gofiber/fiber/v2/middleware/cors" + "ulmer-furs.de/pretix-proxy/v2/app/routes" + "ulmer-furs.de/pretix-proxy/v2/config" +) + +//go:embed app/views/* +var viewFS embed.FS + +func main() { + config.LoadEnv() + config.Connect() + config.SetupValidator() + config.SetupFiber(viewFS) + + if config.Env.Debug { + config.App.Use(cors.New(cors.Config{ + AllowHeaders: "Origin,Content-Type,Accept,Content-Length,Accept-Language,Accept-Encoding,Connection,Access-Control-Allow-Origin", + AllowOrigins: "*", + AllowCredentials: true, + AllowMethods: "GET,POST,HEAD,PUT,DELETE,PATCH,OPTIONS", + })) + } + + routes.PublicRoutes(config.App) + routes.PrivateRoutes(config.App) + + log.Fatal(config.App.Listen(":3000")) +}