dkforest

A forum and chat platform (onion)
git clone https://git.dasho.dev/n0tr1v/dkforest.git
Log | Files | Refs | LICENSE

commit e87f10e85cb5c1b880911d9099875431ec0697fa
parent 5ee0e5c50374f828dcd9507f191e129ae58eb7de
Author: n0tr1v <n0tr1v@protonmail.com>
Date:   Wed, 14 Dec 2022 21:46:37 -0500

improve captcha UX

Diffstat:
Mpkg/web/handlers/data.go | 2++
Mpkg/web/handlers/handlers.go | 23++++++++++++++++-------
Mpkg/web/public/views/pages/captcha.gohtml | 8++++++++
3 files changed, 26 insertions(+), 7 deletions(-)

diff --git a/pkg/web/handlers/data.go b/pkg/web/handlers/data.go @@ -399,6 +399,8 @@ type chatCreateRoomData struct { type captchaData struct { Ts int64 Seed int64 + CaptchaSec int64 + Frames []string CaptchaImg string CaptchaID string Captcha string diff --git a/pkg/web/handlers/handlers.go b/pkg/web/handlers/handlers.go @@ -158,7 +158,7 @@ func protectHomeHandler(c echo.Context) error { // Generate css frames frames := generateCaptchaCssFrames(waitTime, func(i int64) string { return utils.ShortDur(time.Duration(i) * time.Second) - }) + }, true) time.Sleep(utils.RandSec(1, 2)) bufTmp := make([]byte, 0, 1024*4) @@ -785,7 +785,7 @@ func waitPageWrapper(c echo.Context, clb echo.HandlerFunc, cookieName string) er var data1 waitData // Generate css frames - data1.Frames = generateCaptchaCssFrames(waitTime, nil) + data1.Frames = generateCaptchaCssFrames(waitTime, nil, true) data1.WaitTime = waitTime data1.SignupToken = signupToken return c.Render(http.StatusOK, "signup-wait", data1) @@ -851,7 +851,7 @@ func signupHandler(c echo.Context) error { config.SignupPageLoad.Inc() data.CaptchaSec = 120 - data.Frames = generateCaptchaCssFrames(data.CaptchaSec, nil) + data.Frames = generateCaptchaCssFrames(data.CaptchaSec, nil, true) hbCookie, hbCookieErr := c.Cookie(hutils.HBCookieName) hasHBCookie := hbCookieErr == nil && hbCookie.Value != "" @@ -975,14 +975,18 @@ const ( RecoveryGpgValidated ) -func generateCaptchaCssFrames(captchaSec int64, contentFn func(int64) string) (frames []string) { +func generateCaptchaCssFrames(captchaSec int64, contentFn func(int64) string, reverse bool) (frames []string) { step := 100.0 / float64(captchaSec) pct := 0.0 for i := int64(0); i <= captchaSec; i++ { + num := i + if reverse { + num = captchaSec - i + } if contentFn == nil { - frames = append(frames, fmt.Sprintf(`%.2f%% { content: "%d"; }`, pct, captchaSec-i)) + frames = append(frames, fmt.Sprintf(`%.2f%% { content: "%d"; }`, pct, num)) } else { - frames = append(frames, fmt.Sprintf(`%.2f%% { content: "%s"; }`, pct, contentFn(captchaSec-i))) + frames = append(frames, fmt.Sprintf(`%.2f%% { content: "%s"; }`, pct, contentFn(num))) } pct += step } @@ -999,7 +1003,7 @@ func forgotPasswordHandler(c echo.Context) error { data.Step = 1 data.CaptchaSec = 120 - data.Frames = generateCaptchaCssFrames(data.CaptchaSec, nil) + data.Frames = generateCaptchaCssFrames(data.CaptchaSec, nil, true) data.CaptchaID, data.CaptchaImg = captcha.New() @@ -3871,6 +3875,11 @@ func CaptchaHandler(c echo.Context) error { data.Ts = time.Now().UnixMilli() //fmt.Println("Seed:", seed) + data.CaptchaSec = 120 + data.Frames = generateCaptchaCssFrames(data.CaptchaSec, func(i int64) string { + return fmt.Sprintf("%ds", i) + }, false) + if c.Request().Method == http.MethodGet { setCaptcha(data.Seed) return c.Render(http.StatusOK, "captcha", data) diff --git a/pkg/web/public/views/pages/captcha.gohtml b/pkg/web/public/views/pages/captcha.gohtml @@ -1,5 +1,12 @@ {{ define "extra-head" }} <style> + #tutorial_secs:before { + content: "0s"; + animation: {{ .Data.CaptchaSec }}s 1s forwards timer_countdown; + } + @keyframes timer_countdown { + {{ range .Data.Frames -}}{{ . | css }}{{ end -}} + } </style> {{ end }} @@ -33,6 +40,7 @@ </form> <form method="get" class="d-inline mr-2"> <button class="btn btn-secondary btn-sm">{{ t "Reset timer" . }}</button> + <span id="tutorial_secs" class="ml-3"></span> </form> </div> </div>