Fix mCaptcha broken after Vite migration#37492
Conversation
The Webpack-to-Vite migration changed CJS interop behaviour: Rolldown now exposes the whole CJS exports object under `module.default`, making `mCaptcha.default` an object rather than the Widget constructor, and makes `INPUT_NAME` a getter-only namespace binding that cannot be reassigned. Probe for the Widget constructor at both `module.default` and `module.default.default` to cover both interop shapes, then rename the input element created by the widget to `m-captcha-response` (the field name Gitea's backend expects) instead of trying to mutate the read-only `INPUT_NAME` export. Fixes: TypeError: setting getter-only property "INPUT_NAME" Fixes: TypeError: r.default is not a constructor Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
This comment was marked as resolved.
This comment was marked as resolved.
|
We use mcaptcha/vanilla-glue here which is under MIT/APACHE-2.0 https://github.com/mCaptcha/glue/tree/master/LICENSES (funny - we just talked about REUSE and it's the first time I see it in the wild. How timely). You're looking at the backend, not the client I think... |
|
Oh yes, you are right. I misread. I see the package version is So it's a good time to upgrade to the latest release? It's just not easy to find a real mCaptcha user, so if you could try to upgrade and confirm it works, would help a lot. Thank you very much. (And maybe the hacky workaround is not needed anymore after upgrading) |
|
I was already considering dropping mCaptcha because of its low-quality code and near-zero adoption. I'm pretty sure better proof-of-work captchas must exist. We can take up this fix if it's proper, should be testable locally. |
There are some good ones I've heard of, like cap.js and ALTCHA. I use mCaptcha for my own instance since it is one of the only open source options in Gitea besides the image captcha. Keeping mCaptcha around or having another open source option would be nice. |
|
https://github.com/altcha-org/altcha seems much more popular indeed. Not sure what its integration would entail, it does seem to have a go lib available. |
|
Replacement can be another topic and doesn't need to be this this PR's scope. For what I can see, since the bug is there and there are real users, we need to fix it. And this one:
Maybe the new release had fixed some bad designs. @rootful what do you think? |
I could look into that once I have the time to do so |
I've looked into rc2, it has some breaking changes that would need template changes. The Vite interop and field-naming problems still apply to rc2 though. Should I make a separate PR for this? |
Is it possible to do it in this one? If rc2 can be used, no need to keep alpha-3 as an intermediate step |
The new release auto-runs on module evaluation, reading the widget URL from #mcaptcha__token-label[data-mcaptcha_url] and binding to a pre-existing #mcaptcha__token input rather than exposing a Widget constructor. Update the template to render those elements and the loader to set the URL before importing, then rename the resulting input so the form posts the field name services/context/captcha.go expects. The lockfile expansion is upstream-driven: vanilla-glue@0.1.0-rc2 declares jest-environment-jsdom as a runtime dependency, which pulls in jsdom and the @jest/* and @sinonjs/* transitives. Vite tree-shakes them out of the browser bundle. Co-Authored-By: Claude Haiku 4.5 <noreply@anthropic.com>
|
That should be done, tested it on my own instance and it works fine. |
bircni
left a comment
There was a problem hiding this comment.
@wxiaoguang should we wait for silverwind?
* origin/main: (49 commits) ci: lint PR titles with commitlint (go-gitea#37498) Make ServeSetHeaders default to download attachment if filename exists (go-gitea#37552) fix(actions): validate workflow param to prevent 500 error (go-gitea#37546) Fix various problems (go-gitea#37547) docs: fix 4 typos in CHANGELOG.md (go-gitea#37549) [skip ci] Updated translations via Crowdin chore(deps): update action dependencies (go-gitea#37540) fix: Fix `nolyfill` for renovate (go-gitea#37537) Refactor pull request view (7) (go-gitea#37524) Update go js py dependencies (go-gitea#37525) Don't unblock run-level-concurrency-blocked runs in the resolver (go-gitea#37461) Refactor pull request view (6) (go-gitea#37522) Refactor pull request view (5) (go-gitea#37517) fix: persist mirror repository metadata (go-gitea#37519) fix(packages): use file names for generic web downloads (go-gitea#37514) fix: merge autodetect can't close other PRs but only the last one when multiple PRs are pushed at once (go-gitea#37512) Fix update branch protection order (go-gitea#37508) Refactor "flex-list" to "flex-divided-list" (go-gitea#37505) fix: redirect early CLI console logger to stderr (go-gitea#37507) Fix mCaptcha broken after Vite migration (go-gitea#37492) ... # Conflicts: # templates/repo/diff/box.tmpl

After the Webpack-to-Vite migration (#37002), mCaptcha stopped working entirely on the registration page, throwing an error:
TypeError: setting getter-only property "INPUT_NAME"This fix stops trying to mutate the read-only INPUT_NAME export. Instead it probes for the Widget constructor at module.default (direct) or module.default.default (CJS-wrapped), constructs the widget, and then renames the hidden input element it creates to m-captcha-response which is the field name Gitea's backend reads from the submitted form.
Generative AI was used to help with making this PR.