diff --git a/app.go b/app.go index c251c22cc826e5b5a01080cf9741e1af304710eb..2f2e8b76055aa48c8dedceccab3b1f27a846deba 100644 --- a/app.go +++ b/app.go @@ -6,6 +6,7 @@ import ( "os" "time" + "github.com/gofiber/contrib/hcaptcha" "github.com/gofiber/fiber/v3" "github.com/gofiber/fiber/v3/middleware/cors" "github.com/gofiber/fiber/v3/middleware/limiter" @@ -33,11 +34,31 @@ func serve(sig chan os.Signal, db *leveldb.DB) error { }, })) + var captcha fiber.Handler + hCaptchaEnable := conf[hCaptchaSiteKey] != "unset" && conf[hCaptchaSecretKey] != "unset" + + if hCaptchaEnable { + // create hCaptcha middleware if enabled + captcha = hcaptcha.New(hcaptcha.Config{ + SecretKey: conf[hCaptchaSecretKey], + }) + + log.Printf("hCaptcha enabled with site key %q", conf[hCaptchaSiteKey]) + } else { + // empty middleware if disabled + captcha = func(c fiber.Ctx) error { + return c.Next() + } + + log.Printf("hCaptcha disabled because one or both of %q and %q are unset", + confEnv[hCaptchaSiteKey][0], confEnv[hCaptchaSecretKey][0]) + } + // /register - routeRegister(app, db) + routeRegister(app, db, captcha) // /hcaptcha-site-key - routeHCaptchaSiteKey(app) + routeHCaptchaSiteKey(app, !hCaptchaEnable, conf[hCaptchaSiteKey]) // graceful shutdown go func() { diff --git a/captcha.go b/captcha.go index edb3cd2ab66efce6e6b260742705ccd4cbf0f833..73bc8c6fef9b4f9d2b301da96d8f70fb8a06f8f0 100644 --- a/captcha.go +++ b/captcha.go @@ -1,34 +1,24 @@ package main import ( - "log" - "github.com/gofiber/fiber/v3" ) // Route to expose hCaptcha site key -func routeHCaptchaSiteKey(app *fiber.App) { - app.Get("/hcaptcha-site-key", func(c fiber.Ctx) error { - if conf[hCaptchaSiteKey] == "unset" { - return c.Status(fiber.StatusInternalServerError).JSON(fiber.Map{ - "message": "hCaptcha site key not configured", +func routeHCaptchaSiteKey(app *fiber.App, stub bool, siteKey string) { + if stub { + app.Get("/captcha", func(c fiber.Ctx) error { + return c.JSON(fiber.Map{ + "success": false, + "message": "hCaptcha is not enabled on this instance", + }) + }) + } else { + app.Get("/captcha", func(c fiber.Ctx) error { + return c.JSON(fiber.Map{ + "success": true, + "hcaptcha_site_key": siteKey, }) - } - return c.JSON(fiber.Map{ - "hcaptcha_site_key": conf[hCaptchaSiteKey], }) - }) -} - -// Middleware to conditionally apply hCaptcha -func conditionalCaptcha(captcha fiber.Handler) fiber.Handler { - return func(c fiber.Ctx) error { - if conf[hCaptchaSecret] == "unset" { - if verbose { - log.Printf("Captcha bypassed for %q", c.IP()) - } - return c.Next() - } - return captcha(c) } } diff --git a/conf.go b/conf.go index 5a9ed93c521b4bc1591751b0dee095ee8116d88e..a95b71fafe42fc5bae60d13befa533a67b89674b 100644 --- a/conf.go +++ b/conf.go @@ -10,18 +10,18 @@ const ( listenAddr allowedURL hCaptchaSiteKey - hCaptchaSecret + hCaptchaSecretKey verboseLogging ) // env variable, default pairing var confEnv = [...][2]string{ - dbPath: {"DB", "db"}, - listenAddr: {"LISTEN_ADDR", "127.0.0.1:3000"}, - allowedURL: {"ALLOWED_URL", "https://hizla.io"}, - hCaptchaSiteKey: {"HCAPTCHA_SITE_KEY", "unset"}, - hCaptchaSecret: {"HCAPTCHA_SECRET", "unset"}, - verboseLogging: {"VERBOSE", "1"}, + dbPath: {"DB", "db"}, + listenAddr: {"LISTEN_ADDR", "127.0.0.1:3000"}, + allowedURL: {"ALLOWED_URL", "https://hizla.io"}, + hCaptchaSiteKey: {"HCAPTCHA_SITE_KEY", "unset"}, + hCaptchaSecretKey: {"HCAPTCHA_SECRET_KEY", "unset"}, + verboseLogging: {"VERBOSE", "1"}, } // resolved config values diff --git a/register.go b/register.go index 109b9ecddd861258d7e6275a9f38f2d5c849f0fb..02b4f60031e328308469e0fa080950fd8192bb3f 100644 --- a/register.go +++ b/register.go @@ -4,7 +4,6 @@ import ( "log" "regexp" - "github.com/gofiber/contrib/hcaptcha" "github.com/gofiber/fiber/v3" "github.com/syndtr/goleveldb/leveldb" ) @@ -16,13 +15,8 @@ type registration struct { } // Waitlist registration route -func routeRegister(app *fiber.App, db *leveldb.DB) { - - captcha := hcaptcha.New(hcaptcha.Config{ - SecretKey: conf[hCaptchaSecret], - }) - - app.Post("/register", conditionalCaptcha(captcha), func(c fiber.Ctx) error { +func routeRegister(app *fiber.App, db *leveldb.DB, captcha fiber.Handler) { + app.Post("/register", func(c fiber.Ctx) error { req := new(registration) // Parse and validate the request @@ -72,5 +66,5 @@ func routeRegister(app *fiber.App, db *leveldb.DB) { return c.JSON(fiber.Map{ "message": "Email registered successfully", }) - }) + }, captcha) }