GoDoxy/internal/net/gphttp/middleware/captcha/middleware.go
Yuzerion 4a8bd48ad5
Some checks are pending
Docker Image CI (socket-proxy) / build (push) Waiting to run
fix: optimize memory usage, fix agent and code refactor (#118)
* refactor: simplify io code and make utils module independent

* fix(docker): agent and socket-proxy docker event flushing with modified reverse proxy handler

* refactor: remove unused code

* refactor: remove the use of logging module in most code

* refactor: streamline domain mismatch check in certState function

* tweak: use ecdsa p-256 for autocert

* fix(tests): update health check tests for invalid host and add case for port in host

* feat(acme): custom acme directory

* refactor: code refactor and improved context and error handling

* tweak: optimize memory usage under load

* fix(oidc): restore old user matching behavior

* docs: add ChatGPT assistant to README

---------

Co-authored-by: yusing <yusing@6uo.me>
2025-05-25 09:45:57 +08:00

61 lines
1.4 KiB
Go

package captcha
import (
"net/http"
"text/template"
"github.com/rs/zerolog/log"
"github.com/yusing/go-proxy/internal/auth"
"github.com/yusing/go-proxy/internal/net/gphttp"
_ "embed"
)
const cookieName = "godoxy_captcha_session"
//go:embed captcha.html
var captchaPageHTML string
var captchaPage = template.Must(template.New("captcha").Parse(captchaPageHTML))
func PreRequest(p Provider, w http.ResponseWriter, r *http.Request) (proceed bool) {
// check session
sessionID, err := r.Cookie(cookieName)
if err == nil {
session, ok := CaptchaSessions.Load(sessionID.Value)
if ok {
if session.expired() {
CaptchaSessions.Delete(sessionID.Value)
} else {
return true
}
}
}
if !gphttp.GetAccept(r.Header).AcceptHTML() {
gphttp.Forbidden(w, "Captcha is required")
return false
}
if r.Method == http.MethodPost {
err := p.Verify(r)
if err == nil {
session := newCaptchaSession(p)
CaptchaSessions.Store(session.ID, session)
auth.SetTokenCookie(w, r, cookieName, session.ID, p.SessionExpiry())
http.Redirect(w, r, r.URL.Path, http.StatusFound)
return false
}
gphttp.Unauthorized(w, err.Error())
return false
}
// captcha challenge
err = captchaPage.Execute(w, map[string]any{
"ScriptHTML": p.ScriptHTML(),
"FormHTML": p.FormHTML(),
})
if err != nil {
log.Error().Err(err).Msg("failed to execute captcha page")
}
return false
}