package app import ( "crypto/tls" "log" "net" "time" jwt "github.com/gofiber/contrib/jwt" "github.com/gofiber/fiber/v2" "github.com/gofiber/fiber/v2/middleware/cors" "github.com/google/uuid" commonDTO "git.ego.freeddns.org/egommerce/api-entities/common/dto" cnf "git.ego.freeddns.org/egommerce/go-api-pkg/config" "git.ego.freeddns.org/egommerce/identity-service/internal/http" ) var defaultCORS = cors.New( cors.Config{ // DEV CONFIG AllowOrigins: "*", AllowMethods: "GET, POST, PATCH, PUT, DELETE, OPTIONS", AllowHeaders: "Accept, Authorization, Content-Type, Vary, X-Request-Id", // PROD CONFIG // AllowOrigins: "http://egommerce.io:3001", // client(reactjs) app url // AllowCredentials: true, // AllowMethods: "GET, POST, PATCH, PUT, DELETE", }, ) type ( Server struct { *fiber.App *PluginManager ID string addr string // e.g. "127.0.0.1:443" } ) func NewServer(c *Config) *Server { return &Server{ ID: c.ID, App: fiber.New(fiber.Config{ AppName: c.ID, ServerHeader: c.getAppFullName(), ReadTimeout: c.ReadTimeout * time.Millisecond, WriteTimeout: c.WriteTimeout * time.Millisecond, IdleTimeout: c.IdleTimeout * time.Millisecond, }), PluginManager: NewPluginManager(), addr: c.NetAddr, } } func (s *Server) Start() error { s.setupMiddleware() s.setupRouter() crt, err := tls.LoadX509KeyPair("certs/identity-svc.crt", "certs/identity-svc.key") if err != nil { log.Fatal("failed to load certificates: ", err) } tlsCnf := &tls.Config{Certificates: []tls.Certificate{crt}} ln, _ := net.Listen("tcp", s.addr) ln = tls.NewListener(ln, tlsCnf) return s.Listener(ln) } func (s *Server) OnShutdown() { log.Printf("Server %s is going down...", s.ID) s.GetDatabase().Close() s.GetCache().Close() s.Shutdown() } func (s *Server) setupRouter() { s.Options("*", defaultCORS) s.Use(defaultCORS) s.Get("/health", http.HealthHandlerFn(s.GetDatabase(), s.GetCache())) s.Group("/v1"). Post("/login", http.LoginHandlerFn(s.GetDatabase(), s.GetCache())). Post("/refresh", http.RefreshHandlerFn(s.GetDatabase(), s.GetCache())). // add JWTProtected() and get token from Auth Bearer header not from the body? Post("/register", http.RegisterHandlerFn(s.GetDatabase(), s.GetCache())). Get("/access" /*JWTProtected(), */, http.AccessHandlerFn(s.GetDatabase(), s.GetCache())) } func (s *Server) setupMiddleware() { s.Use(LoggingMiddleware()) s.Use(XRequestIDMiddleware()) } func LoggingMiddleware() func(c *fiber.Ctx) error { return func(c *fiber.Ctx) error { log.Printf("Request: %s, remote: %s", c.Request().URI().String(), c.Context().RemoteIP().String(), ) return c.Next() } } func XRequestIDMiddleware() func(c *fiber.Ctx) error { return func(c *fiber.Ctx) error { c.Set("X-Request-ID", uuid.New().String()) return c.Next() } } func JWTProtected() func(c *fiber.Ctx) error { secret := []byte(cnf.GetEnv("JWT_ACCESS_TOKEN_SECRET_KEY", "FallbackAccessTokenSecret")) return jwt.New(jwt.Config{ SigningKey: jwt.SigningKey{Key: secret}, ContextKey: "jwt", ErrorHandler: func(c *fiber.Ctx, err error) error { return c.Status(fiber.StatusUnauthorized).JSON(commonDTO.ErrorResponseDTO{Error: "unauthorized"}) }, }) }