Skip to content

Fix mCaptcha broken after Vite migration#37492

Merged
bircni merged 9 commits into
go-gitea:mainfrom
rootful:fix-mcaptcha-vite-interop
May 2, 2026
Merged

Fix mCaptcha broken after Vite migration#37492
bircni merged 9 commits into
go-gitea:mainfrom
rootful:fix-mcaptcha-vite-interop

Conversation

@rootful
Copy link
Copy Markdown
Contributor

@rootful rootful commented Apr 30, 2026

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.

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>
@GiteaBot GiteaBot added the lgtm/need 2 This PR needs two approvals by maintainers to be considered for merging. label Apr 30, 2026
@wxiaoguang

This comment was marked as resolved.

@TheFox0x7
Copy link
Copy Markdown
Contributor

TheFox0x7 commented Apr 30, 2026

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...

@wxiaoguang
Copy link
Copy Markdown
Contributor

wxiaoguang commented Apr 30, 2026

Oh yes, you are right. I misread.

I see the package version is 0.1.0-rc2, but our version is 0.1.0-alpha-3.

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)

@lunny lunny requested a review from silverwind April 30, 2026 16:23
@lunny lunny added type/bug backport/v1.26 This PR should be backported to Gitea 1.26 labels Apr 30, 2026
@silverwind
Copy link
Copy Markdown
Member

silverwind commented Apr 30, 2026

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.

@rootful
Copy link
Copy Markdown
Contributor Author

rootful commented Apr 30, 2026

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.

@silverwind
Copy link
Copy Markdown
Member

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.

@wxiaoguang
Copy link
Copy Markdown
Contributor

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:

I see the package version is 0.1.0-rc2, but our version is 0.1.0-alpha-3. So it's a good time to upgrade to the latest release?

Maybe the new release had fixed some bad designs.

@rootful what do you think?

@rootful
Copy link
Copy Markdown
Contributor Author

rootful commented May 1, 2026

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

@rootful
Copy link
Copy Markdown
Contributor Author

rootful commented May 1, 2026

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:

I see the package version is 0.1.0-rc2, but our version is 0.1.0-alpha-3. So it's a good time to upgrade to the latest release?

Maybe the new release had fixed some bad designs.

@rootful what do you think?

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?

@wxiaoguang
Copy link
Copy Markdown
Contributor

wxiaoguang commented May 1, 2026

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>
@rootful
Copy link
Copy Markdown
Contributor Author

rootful commented May 1, 2026

That should be done, tested it on my own instance and it works fine.

Comment thread web_src/js/features/captcha.ts Outdated
@wxiaoguang
Copy link
Copy Markdown
Contributor

Can be as simple as this, most JS code can be removed.

ac2052b

image

@GiteaBot GiteaBot added lgtm/need 1 This PR needs approval from one additional maintainer to be merged. and removed lgtm/need 2 This PR needs two approvals by maintainers to be considered for merging. labels May 1, 2026
Copy link
Copy Markdown
Member

@bircni bircni left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@wxiaoguang should we wait for silverwind?

@GiteaBot GiteaBot added lgtm/done This PR has enough approvals to get merged. There are no important open reservations anymore. and removed lgtm/need 1 This PR needs approval from one additional maintainer to be merged. labels May 1, 2026
@lunny lunny added the reviewed/wait-merge This pull request is part of the merge queue. It will be merged soon. label May 1, 2026
@bircni bircni merged commit 3d838ef into go-gitea:main May 2, 2026
22 checks passed
@GiteaBot GiteaBot added this to the 1.27.0 milestone May 2, 2026
@GiteaBot GiteaBot removed the reviewed/wait-merge This pull request is part of the merge queue. It will be merged soon. label May 2, 2026
@GiteaBot GiteaBot added the backport/done All backports for this PR have been created label May 2, 2026
@rootful rootful deleted the fix-mcaptcha-vite-interop branch May 2, 2026 17:06
silverwind added a commit to McMichalK/gitea that referenced this pull request May 5, 2026
* 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
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

backport/done All backports for this PR have been created backport/v1.26 This PR should be backported to Gitea 1.26 lgtm/done This PR has enough approvals to get merged. There are no important open reservations anymore. type/bug

Projects

None yet

Development

Successfully merging this pull request may close these issues.

7 participants