| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103 |
- package main
- import (
- "auto-ssl/config"
- "auto-ssl/handlers"
- "auto-ssl/services"
- "log"
- "os"
- "time"
- "github.com/gin-contrib/cors"
- "github.com/gin-gonic/gin"
- "github.com/robfig/cron/v3"
- )
- func main() {
- cfg := config.Load()
- // Initialize database
- config.InitDB(cfg)
- // Setup Gin
- gin.SetMode(gin.ReleaseMode)
- r := gin.Default()
- // CORS for Vue frontend
- r.Use(cors.New(cors.Config{
- AllowOrigins: []string{"*"},
- AllowMethods: []string{"GET", "POST", "PUT", "DELETE", "OPTIONS"},
- AllowHeaders: []string{"Origin", "Content-Type", "Accept", "Authorization"},
- AllowCredentials: true,
- }))
- // Serve static files for frontend
- r.Static("/assets", "./dist/assets")
- r.StaticFile("/favicon.ico", "./dist/favicon.ico")
- r.StaticFile("/", "./dist/index.html")
- r.NoRoute(func(c *gin.Context) {
- c.File("./dist/index.html")
- })
- // API routes
- api := r.Group("/api")
- {
- certHandler := handlers.NewCertHandler(cfg)
- // Certificate management
- api.GET("/certificates", certHandler.ListCertificates)
- api.GET("/certificates/:id", certHandler.GetCertificate)
- api.POST("/certificates", certHandler.CreateCertificate)
- api.PUT("/certificates/:id", certHandler.UpdateCertificate)
- api.DELETE("/certificates/:id", certHandler.DeleteCertificate)
- api.POST("/certificates/:id/renew", certHandler.RenewCertificate)
- api.GET("/certificates/:id/files", certHandler.GetCertFiles)
- // Utility
- api.GET("/renewals/check", certHandler.CheckRenewals)
- api.GET("/stats", certHandler.Stats)
- }
- // Setup cron for auto-renewal (runs daily at 3:00 AM)
- c := cron.New()
- c.AddFunc("0 3 * * *", func() {
- log.Println("Running scheduled certificate renewal check...")
- var certs []config.Certificate
- config.DB.Where("auto_renew = ? AND status = ?", true, "active").Find(&certs)
- for _, cert := range certs {
- if cert.ExpiresAt != nil && time.Until(*cert.ExpiresAt).Hours() < float64(cert.RenewDays*24) {
- log.Printf("Auto-renewing certificate for %s (expires %s)", cert.Domain, cert.ExpiresAt.Format(time.RFC3339))
- if err := services.RenewCertificate(&cert, cfg); err != nil {
- cert.Status = "error"
- cert.ErrorMessage = "auto renew: " + err.Error()
- log.Printf("Auto-renew failed for %s: %v", cert.Domain, err)
- } else {
- log.Printf("Auto-renew succeeded for %s", cert.Domain)
- }
- config.DB.Save(&cert)
- }
- }
- })
- c.Start()
- // Setup HTTP server for ACME HTTP-01 challenges (port 80)
- httpPort := os.Getenv("HTTP_PORT")
- if httpPort == "" {
- httpPort = "80"
- }
- go func() {
- acme := gin.New()
- acme.Use(gin.Recovery())
- // HTTP-01 challenge handler from lego
- log.Printf("ACME HTTP challenge server listening on :%s", httpPort)
- if err := acme.Run(":" + httpPort); err != nil {
- log.Printf("ACME HTTP server (port %s) exited: %v", httpPort, err)
- }
- }()
- log.Printf("AutoSSL server starting on :%s", cfg.Port)
- if err := r.Run(":" + cfg.Port); err != nil {
- log.Fatalf("Failed to start server: %v", err)
- }
- }
|