Heavier rate limiting for POST and other methods may create data

This commit is contained in:
LittleSheep 2025-03-22 19:23:45 +08:00
parent c8bba4fb2d
commit ba1d96b118
4 changed files with 115 additions and 0 deletions

View File

@ -13,6 +13,7 @@ FROM golang:alpine
RUN apk add postgresql-client
COPY --from=nexus-server /dist /nexus/server
COPY ./templates /templates
EXPOSE 8444

View File

@ -12,6 +12,7 @@ import (
"github.com/gofiber/fiber/v2/middleware/idempotency"
"github.com/gofiber/fiber/v2/middleware/limiter"
"github.com/rs/zerolog/log"
"github.com/samber/lo"
"github.com/spf13/viper"
)
@ -51,6 +52,17 @@ func NewServer() *WebApp {
Max: viper.GetInt("rate_limit"),
Expiration: 60 * time.Second,
LimiterMiddleware: limiter.SlidingWindow{},
Next: func(c *fiber.Ctx) bool {
return lo.Contains([]string{"GET", "HEAD", "OPTIONS", "CONNECT", "TRACE"}, c.Method())
},
}))
app.Use(limiter.New(limiter.Config{
Max: viper.GetInt("rate_limit_advance"),
Expiration: 60 * time.Second,
LimiterMiddleware: limiter.SlidingWindow{},
Next: func(c *fiber.Ctx) bool {
return lo.Contains([]string{"POST", "PUT", "DELETE", "PATCH"}, c.Method())
},
}))
api.MapControllers(app)

View File

@ -3,6 +3,7 @@ grpc_bind = "0.0.0.0:7001"
domain = "localhost"
rate_limit = 120
rate_limit_advance = 60
[debug]
database = false
@ -25,3 +26,8 @@ internal_private_key = "keys/internal_private_key.pem"
[watchtower]
database_backups = "./backups"
[captcha]
provider = "turnstile"
api_key = ""
api_secret = ""

96
templates/captcha.tmpl Normal file
View File

@ -0,0 +1,96 @@
<!doctype html>
<html lang="en">
<head>
<meta charset="UTF-8" />
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
<title>Cloudflare Turnstile</title>
<link
href="https://fonts.googleapis.com/css2?family=Roboto+Mono&display=swap"
rel="stylesheet"
/>
<style>
body {
display: flex;
flex-direction: column;
justify-content: center;
align-items: center;
height: 100vh;
background-color: #2d2d2d;
font-family: "Roboto Mono", monospace;
color: #c9d1d9;
}
.parent {
padding: 20px;
max-width: 480px;
margin: 0 auto;
}
h2 {
font-size: 18px;
font-weight: 300;
color: #ffffff;
margin-bottom: 15px;
}
.footer {
margin-top: 20px;
font-size: 11px;
opacity: 0.6;
}
.footer-product {
font-size: 12px;
font-weight: bold;
margin-bottom: 5px;
opacity: 0.8;
}
</style>
<script
src="https://challenges.cloudflare.com/turnstile/v0/api.js"
async
defer
></script>
</head>
<body>
<div class="parent">
<div class="container">
<h1>reCaptcha</h1>
<div
class="cf-turnstile"
data-sitekey="{{ .APIKey }}"
data-callback="onSuccess"
></div>
</div>
<div class="footer">
<div class="footer-product">Solar Network Captcha Gateway</div>
<a
href="https://solsynth.dev"
style="color: #c9d1d9; text-decoration: none"
>Solsynth LLC</a
>
&copy; 2025<br />
Powered by
<a href="https://www.cloudflare.com/turnstile/" style="color: #c9d1d9"
>Cloudflare Turnstile</a
>
<br />
Hosted by
<a
href="https://github.com/Solsynth/HyperNet.Nexus"
style="color: #c9d1d9"
>HyperNet.Nexus</a
>
</div>
</div>
<script>
function getQueryParam(name) {
const urlParams = new URLSearchParams(window.location.search);
return urlParams.get(name);
}
function onSuccess(token) {
const redirectUri = getQueryParam("redirect_uri");
if (redirectUri) {
window.location.href = `${redirectUri}?captcha_tk=${encodeURIComponent(token)}`;
}
}
</script>
</body>
</html>