From: PhiTux Date: Fri, 3 Oct 2025 21:17:27 +0000 (+0200) Subject: admin can open registration for 5 minutes X-Git-Url: http://git.99rst.org/?a=commitdiff_plain;h=9a42ba8a3f2e8153b044abb327e6d49b5fb81f30;p=DailyTxT.git admin can open registration for 5 minutes --- diff --git a/backend/handlers/admin.go b/backend/handlers/admin.go index 930b8fe..e62cfa3 100644 --- a/backend/handlers/admin.go +++ b/backend/handlers/admin.go @@ -9,6 +9,7 @@ import ( "strconv" "strings" "syscall" + "time" "github.com/phitux/dailytxt/backend/utils" ) @@ -288,3 +289,39 @@ func DeleteOldData(w http.ResponseWriter, r *http.Request) { "success": true, }) } + +// OpenRegistrationTemp allows admin to open registration for a limited time window +func OpenRegistrationTemp(w http.ResponseWriter, r *http.Request) { + // Decode request (admin password + optional seconds) + var req struct { + AdminPassword string `json:"admin_password"` + Seconds int `json:"seconds"` + } + if err := json.NewDecoder(r.Body).Decode(&req); err != nil { + http.Error(w, "Invalid request", http.StatusBadRequest) + return + } + + adminPassword := os.Getenv("ADMIN_PASSWORD") + if adminPassword == "" || req.AdminPassword != adminPassword { + http.Error(w, "Invalid admin password", http.StatusUnauthorized) + return + } + + log.Printf("%v", r.Body) + + // Default duration 5 minutes; optionally allow custom seconds (max 15 min) + duration := 5 * 60 // seconds + if req.Seconds > 0 && req.Seconds <= 15*60 { + duration = req.Seconds + } + + utils.SetRegistrationOverride(time.Duration(duration) * time.Second) + + w.Header().Set("Content-Type", "application/json") + json.NewEncoder(w).Encode(map[string]any{ + "success": true, + "until": time.Now().Add(time.Duration(duration) * time.Second).Format(time.RFC3339), + "duration": duration, + }) +} diff --git a/backend/handlers/users.go b/backend/handlers/users.go index 435c895..540af30 100644 --- a/backend/handlers/users.go +++ b/backend/handlers/users.go @@ -219,9 +219,13 @@ func Login(w http.ResponseWriter, r *http.Request) { } func IsRegistrationAllowed(w http.ResponseWriter, r *http.Request) { - // Check if registration is allowed - utils.JSONResponse(w, http.StatusOK, map[string]bool{ - "registration_allowed": utils.Settings.AllowRegistration, + + // Check if registration is allowed (consider env and temporary override) + allowed, tempAllowed := utils.IsRegistrationAllowed() + utils.JSONResponse(w, http.StatusOK, map[string]any{ + "registration_allowed": allowed, + "temporary_allowed": tempAllowed, + "until": utils.GetRegistrationOverrideUntil(), }) } @@ -234,7 +238,7 @@ type RegisterRequest struct { // Register handles user registration // The API endpoint func RegisterHandler(w http.ResponseWriter, r *http.Request) { - if !utils.Settings.AllowRegistration { + if allowed, temporary := utils.IsRegistrationAllowed(); !allowed && !temporary { http.Error(w, "Registration is not allowed", http.StatusForbidden) return } diff --git a/backend/main.go b/backend/main.go index 630215e..a686378 100644 --- a/backend/main.go +++ b/backend/main.go @@ -109,6 +109,7 @@ func main() { mux.HandleFunc("POST /admin/get-data", middleware.RequireAuth(handlers.GetAdminData)) mux.HandleFunc("POST /admin/delete-user", middleware.RequireAuth(handlers.DeleteUser)) mux.HandleFunc("POST /admin/delete-old-data", middleware.RequireAuth(handlers.DeleteOldData)) + mux.HandleFunc("POST /admin/open-registration", middleware.RequireAuth(handlers.OpenRegistrationTemp)) // Create a handler chain with Timeout, Logger and CORS middleware // Timeout middleware will be executed first, then Logger, then CORS diff --git a/backend/utils/helpers.go b/backend/utils/helpers.go index c3a020f..fc76d6b 100644 --- a/backend/utils/helpers.go +++ b/backend/utils/helpers.go @@ -9,6 +9,7 @@ import ( "os" "strconv" "strings" + "sync" "time" ) @@ -47,6 +48,39 @@ type AppSettings struct { // Global settings var Settings AppSettings +// Registration override state (temporary window to allow registration) +var ( + registrationOverrideUntil time.Time + registrationOverrideMu sync.RWMutex +) + +// SetRegistrationOverride opens registration for the given duration +func SetRegistrationOverride(d time.Duration) { + registrationOverrideMu.Lock() + defer registrationOverrideMu.Unlock() + registrationOverrideUntil = time.Now().Add(d) + Logger.Printf("Registration temporarily opened until %s", registrationOverrideUntil.Format(time.RFC3339)) +} + +func GetRegistrationOverrideUntil() time.Time { + registrationOverrideMu.RLock() + defer registrationOverrideMu.RUnlock() + return registrationOverrideUntil +} + +// IsRegistrationAllowed returns whether registration is +// overall allowed or temporarily allowed +func IsRegistrationAllowed() (bool, bool) { + allowed := Settings.AllowRegistration + + registrationOverrideMu.RLock() + until := registrationOverrideUntil + registrationOverrideMu.RUnlock() + tempAllowed := time.Now().Before(until) + + return allowed, tempAllowed +} + // SetVersion sets the application version func SetVersion(version string) { AppVersion = version diff --git a/frontend/src/lib/settings/Admin.svelte b/frontend/src/lib/settings/Admin.svelte index 81d4b2b..70342ff 100644 --- a/frontend/src/lib/settings/Admin.svelte +++ b/frontend/src/lib/settings/Admin.svelte @@ -1,5 +1,5 @@