package main import ( "log" "net/http" "os" "strconv" "strings" "time" "momswap/backend/internal/app" httpapi "momswap/backend/internal/http" "momswap/backend/internal/storage" "momswap/backend/internal/store" ) func main() { addr := getEnv("ADDR", ":8122") adminPublicKey := os.Getenv("ADMIN_PUBLIC_KEY") servicePublicKey := getEnv("SERVICE_PUBLIC_KEY", adminPublicKey) if adminPublicKey == "" { adminPublicKey = readKeyFile(getEnv("ADMIN_PUBLIC_KEY_FILE", "etc/server-service.pub")) } if servicePublicKey == "" { servicePublicKey = readKeyFile(getEnv("SERVICE_PUBLIC_KEY_FILE", "etc/server-service.pub")) } if servicePublicKey == "" { servicePublicKey = adminPublicKey } var st store.Store if databaseURL := os.Getenv("DATABASE_URL"); databaseURL != "" { if err := store.Migrate(databaseURL); err != nil { log.Fatalf("migrate: %v", err) } pg, err := store.NewPostgresStore(databaseURL) if err != nil { log.Fatalf("postgres: %v", err) } defer pg.Close() st = pg } else { st = store.NewMemoryStore() } service := app.NewService(st, app.Config{ ChallengeTTL: 5 * time.Minute, SessionTTL: 24 * time.Hour, }, servicePublicKey) service.BootstrapAdmin(adminPublicKey) if signer, err := newAssetSignerFromEnv(); err != nil { log.Printf("asset storage disabled: %v", err) } else if signer != nil { service.ConfigureAssetStorage(signer) } api := httpapi.NewAPI(service) log.Printf("listening on %s", addr) if err := http.ListenAndServe(addr, api.Routes()); err != nil { log.Fatalf("listen: %v", err) } } func newAssetSignerFromEnv() (app.AssetURLSigner, error) { endpoint := os.Getenv("S3_ENDPOINT") bucket := os.Getenv("S3_BUCKET") if endpoint == "" || bucket == "" { return nil, nil } useTLS, err := strconv.ParseBool(getEnv("S3_USE_TLS", "false")) if err != nil { return nil, err } usePathStyle, err := strconv.ParseBool(getEnv("S3_USE_PATH_STYLE", "true")) if err != nil { return nil, err } signer, err := storage.NewS3Signer(storage.S3Config{ Endpoint: endpoint, Region: getEnv("S3_REGION", "us-east-1"), Bucket: bucket, AccessKey: getEnv("S3_ACCESS_KEY", ""), SecretKey: getEnv("S3_SECRET_KEY", ""), UseTLS: useTLS, PathStyle: usePathStyle, }) if err != nil { return nil, err } return signer, nil } func getEnv(key, fallback string) string { v := os.Getenv(key) if v == "" { return fallback } return v } func readKeyFile(path string) string { b, err := os.ReadFile(path) if err != nil { return "" } return strings.TrimSpace(string(b)) }