package system import ( "context" "crypto/sha256" "crypto/subtle" "encoding/base64" "net/url" "os" "path/filepath" "strings" "time" account "git.ipao.vip/rogee/creator-hub/internal/account" "git.ipao.vip/rogee/creator-hub/internal/creator" hub "git.ipao.vip/rogee/creator-hub/internal/environment" "github.com/gofiber/fiber/v3" "github.com/sirupsen/logrus" ) func RegisterHealth(app *fiber.App, accountStore *account.Store, environmentStore *hub.Store, creatorStore *creator.Store) { app.Get("/healthz", func(c fiber.Ctx) error { c.Status(fiber.StatusNoContent) return nil }) app.Get("/readyz", func(c fiber.Ctx) error { if accountStore == nil || environmentStore == nil || creatorStore == nil { return c.Status(fiber.StatusServiceUnavailable).JSON(fiber.Map{"error": "service is not ready"}) } ctx, cancel := context.WithTimeout(c.Context(), 2*time.Second) defer cancel() checks := []struct { name string fn func(context.Context) error }{ {"phase_a", accountStore.Ping}, {"hub", environmentStore.Ping}, {"creator", creatorStore.Ping}, {"creator_schema", creatorStore.EnsureSchema}, } for _, check := range checks { if err := check.fn(ctx); err != nil { logrus.WithError(err).WithField("check", check.name).Warn("control plane readiness check failed") return c.Status(fiber.StatusServiceUnavailable).JSON(fiber.Map{"error": "service is not ready"}) } } c.Status(fiber.StatusNoContent) return nil }) } func Authenticate(username, password string) fiber.Handler { wantUser, wantPassword := sha256.Sum256([]byte(username)), sha256.Sum256([]byte(password)) return func(c fiber.Ctx) error { encoded, ok := strings.CutPrefix(c.Get(fiber.HeaderAuthorization), "Basic ") decoded, err := base64.StdEncoding.DecodeString(encoded) user, suppliedPassword, found := strings.Cut(string(decoded), ":") gotUser, gotPassword := sha256.Sum256([]byte(user)), sha256.Sum256([]byte(suppliedPassword)) if !ok || err != nil || !found || subtle.ConstantTimeCompare(gotUser[:], wantUser[:]) != 1 || subtle.ConstantTimeCompare(gotPassword[:], wantPassword[:]) != 1 { c.Set(fiber.HeaderWWWAuthenticate, `Basic realm="CreatorHub", charset="UTF-8"`) return c.Status(fiber.StatusUnauthorized).JSON(map[string]string{"error": "authentication required"}) } return c.Next() } } func IsAPIPath(path string) bool { for _, prefix := range []string{"/api", "/phase-a", "/gateways", "/browsers", "/network-exits"} { if path == prefix || strings.HasPrefix(path, prefix+"/") { return true } } return false } func SPAHandler(directory string) fiber.Handler { return func(c fiber.Ctx) error { path, err := url.PathUnescape(strings.TrimPrefix(c.Path(), "/")) path = filepath.Clean(path) if err == nil && filepath.IsLocal(path) { name := filepath.Join(directory, path) if info, err := os.Stat(name); err == nil && !info.IsDir() { return c.SendFile(name) } } return c.SendFile(filepath.Join(directory, "index.html")) } }