From d56af8e9e954fec5ab1e2d14d92d0113e48c425d Mon Sep 17 00:00:00 2001 From: Gusted Date: Fri, 22 Jul 2022 14:31:53 +0200 Subject: [PATCH 01/14] Add config stuff --- docs/content/doc/advanced/config-cheat-sheet.en-us.md | 7 +++++-- modules/setting/service.go | 6 ++++++ 2 files changed, 11 insertions(+), 2 deletions(-) diff --git a/docs/content/doc/advanced/config-cheat-sheet.en-us.md b/docs/content/doc/advanced/config-cheat-sheet.en-us.md index a0e6fb8f13b1b..14e1548ee5a61 100644 --- a/docs/content/doc/advanced/config-cheat-sheet.en-us.md +++ b/docs/content/doc/advanced/config-cheat-sheet.en-us.md @@ -576,13 +576,16 @@ Certain queues have defaults that override the defaults set in `[queue]` (this o provided email rather than a generated email. - `ENABLE_CAPTCHA`: **false**: Enable this to use captcha validation for registration. - `REQUIRE_EXTERNAL_REGISTRATION_CAPTCHA`: **false**: Enable this to force captcha validation - even for External Accounts (i.e. GitHub, OpenID Connect, etc). You must `ENABLE_CAPTCHA` also. -- `CAPTCHA_TYPE`: **image**: \[image, recaptcha, hcaptcha\] + even for External Accounts (i.e. GitHub, OpenID Connect, etc). You also must enable `ENABLE_CAPTCHA`. +- `CAPTCHA_TYPE`: **image**: \[image, recaptcha, hcaptcha, mcaptcha\] - `RECAPTCHA_SECRET`: **""**: Go to https://www.google.com/recaptcha/admin to get a secret for recaptcha. - `RECAPTCHA_SITEKEY`: **""**: Go to https://www.google.com/recaptcha/admin to get a sitekey for recaptcha. - `RECAPTCHA_URL`: **https://www.google.com/recaptcha/**: Set the recaptcha url - allows the use of recaptcha net. - `HCAPTCHA_SECRET`: **""**: Sign up at https://www.hcaptcha.com/ to get a secret for hcaptcha. - `HCAPTCHA_SITEKEY`: **""**: Sign up at https://www.hcaptcha.com/ to get a sitekey for hcaptcha. +- `MCAPTCHA_SECRET`: **""**: Go to your mCaptcha instance to get a secret for mCaptcha. +- `MCAPTCHA_SITEKEY`: **""**: Go to your mCaptcha instance to get a sitekey for mCaptcha. +- `MCAPTCHA_URL` **https://demo.mcaptcha.org/**: Set the mCaptcha URL. - `DEFAULT_KEEP_EMAIL_PRIVATE`: **false**: By default set users to keep their email address private. - `DEFAULT_ALLOW_CREATE_ORGANIZATION`: **true**: Allow new users to create organizations by default. - `DEFAULT_USER_IS_RESTRICTED`: **false**: Give new users restricted permissions by default diff --git a/modules/setting/service.go b/modules/setting/service.go index bd97e10b0f0dc..af8a72cc6dba6 100644 --- a/modules/setting/service.go +++ b/modules/setting/service.go @@ -47,6 +47,9 @@ var Service = struct { RecaptchaURL string HcaptchaSecret string HcaptchaSitekey string + McaptchaSecret string + McaptchaSitekey string + McaptchaURL string DefaultKeepEmailPrivate bool DefaultAllowCreateOrganization bool DefaultUserIsRestricted bool @@ -133,6 +136,9 @@ func newService() { Service.RecaptchaURL = sec.Key("RECAPTCHA_URL").MustString("https://www.google.com/recaptcha/") Service.HcaptchaSecret = sec.Key("HCAPTCHA_SECRET").MustString("") Service.HcaptchaSitekey = sec.Key("HCAPTCHA_SITEKEY").MustString("") + Service.McaptchaURL = sec.Key("MCAPTCHA_URL").MustString("https://demo.mcaptcha.org/") + Service.McaptchaSecret = sec.Key("MCAPTCHA_SECRET").MustString("") + Service.McaptchaSitekey = sec.Key("MCAPTCHA_SITEKEY").MustString("") Service.DefaultKeepEmailPrivate = sec.Key("DEFAULT_KEEP_EMAIL_PRIVATE").MustBool() Service.DefaultAllowCreateOrganization = sec.Key("DEFAULT_ALLOW_CREATE_ORGANIZATION").MustBool(true) Service.DefaultUserIsRestricted = sec.Key("DEFAULT_USER_IS_RESTRICTED").MustBool(false) From 46be033c7fcfb4c8e03d59a842a061ce6611fd6c Mon Sep 17 00:00:00 2001 From: Gusted Date: Fri, 22 Jul 2022 16:49:24 +0200 Subject: [PATCH 02/14] Load mCaptcha on register page --- custom/conf/app.example.ini | 11 +++- modules/setting/setting.go | 1 + package-lock.json | 63 +++++++++++++++++++ package.json | 1 + routers/web/auth/auth.go | 4 ++ routers/web/auth/linkaccount.go | 6 ++ routers/web/auth/openid.go | 4 ++ templates/user/auth/signup_inner.tmpl | 8 +++ .../user/auth/signup_openid_register.tmpl | 5 ++ web_src/js/features/mcaptcha.js | 15 +++++ web_src/js/index.js | 2 + 11 files changed, 118 insertions(+), 2 deletions(-) create mode 100644 web_src/js/features/mcaptcha.js diff --git a/custom/conf/app.example.ini b/custom/conf/app.example.ini index 08708948940fa..c39a212d7e622 100644 --- a/custom/conf/app.example.ini +++ b/custom/conf/app.example.ini @@ -699,6 +699,8 @@ ROUTER = console ;; Type of captcha you want to use. Options: image, recaptcha, hcaptcha ;CAPTCHA_TYPE = image ;; +;; Change this to use recaptcha.net or other recaptcha service +;RECAPTCHA_URL = https://www.google.com/recaptcha/ ;; Enable recaptcha to use Google's recaptcha service ;; Go to https://www.google.com/recaptcha/admin to sign up for a key ;RECAPTCHA_SECRET = @@ -708,8 +710,13 @@ ROUTER = console ;HCAPTCHA_SECRET = ;HCAPTCHA_SITEKEY = ;; -;; Change this to use recaptcha.net or other recaptcha service -;RECAPTCHA_URL = https://www.google.com/recaptcha/ +;; Change this to use demo.mcaptcha.org or your self-hosted mcaptcha.org instance. +;MCAPTCHA_URL = https://demo.mcaptcha.org +;; +;; Go to your configured mCaptcha instance and register a sitekey +;; and use your account's secret. +;MCAPTCHA_SECRET = +;MCAPTCHA_SITEKEY = ;; ;; Default value for KeepEmailPrivate ;; Each new user will get the value of this setting copied into their profile diff --git a/modules/setting/setting.go b/modules/setting/setting.go index 23e3280dc9f10..d9f2d8f393b89 100644 --- a/modules/setting/setting.go +++ b/modules/setting/setting.go @@ -59,6 +59,7 @@ const ( ImageCaptcha = "image" ReCaptcha = "recaptcha" HCaptcha = "hcaptcha" + MCaptcha = "mcaptcha" ) // settings diff --git a/package-lock.json b/package-lock.json index d2aa3dbe1b2e9..dcdbff636d664 100644 --- a/package-lock.json +++ b/package-lock.json @@ -8,6 +8,7 @@ "license": "MIT", "dependencies": { "@claviska/jquery-minicolors": "2.3.6", + "@mcaptcha/vanilla-glue": "0.1.0-alpha-1", "@primer/octicons": "17.3.0", "add-asset-webpack-plugin": "2.0.1", "css-loader": "6.7.1", @@ -1634,6 +1635,55 @@ "jsep": "^0.4.0||^1.0.0" } }, + "node_modules/@mcaptcha/core-glue": { + "version": "0.1.0-alpha-3", + "resolved": "https://registry.npmjs.org/@mcaptcha/core-glue/-/core-glue-0.1.0-alpha-3.tgz", + "integrity": "sha512-avphBVgf3PPDWuUoDsB2qiXAss2pc00lUILswJaMQofr8FQyflzkhha8H2Z+qGFiX0Iib/yyP2TOtBDbHqE9Tg==", + "funding": [ + { + "type": "individual", + "url": "http://mcaptcha.org/donate" + }, + { + "type": "liberapay", + "url": "https://liberapay.com/mcaptcha" + }, + { + "type": "individual", + "url": "http://batsense.net/donate" + }, + { + "type": "liberapay", + "url": "https://liberapay.com/realaravinth" + } + ] + }, + "node_modules/@mcaptcha/vanilla-glue": { + "version": "0.1.0-alpha-1", + "resolved": "https://registry.npmjs.org/@mcaptcha/vanilla-glue/-/vanilla-glue-0.1.0-alpha-1.tgz", + "integrity": "sha512-GHPjUpqdgk9DquGnGYGDQertcwMENKUc4yr/Q3M7WzL6rPBs6JMCVdDHV22RGTxk3xBM19fGuDQ8GOyNauQ3hg==", + "funding": [ + { + "type": "individual", + "url": "http://mcaptcha.org/donate" + }, + { + "type": "liberapay", + "url": "https://liberapay.com/mcaptcha" + }, + { + "type": "individual", + "url": "http://batsense.net/donate" + }, + { + "type": "liberapay", + "url": "https://liberapay.com/realaravinth" + } + ], + "dependencies": { + "@mcaptcha/core-glue": "^0.1.0-alpha-3" + } + }, "node_modules/@nodelib/fs.scandir": { "version": "2.1.5", "resolved": "https://registry.npmjs.org/@nodelib/fs.scandir/-/fs.scandir-2.1.5.tgz", @@ -13779,6 +13829,19 @@ "dev": true, "requires": {} }, + "@mcaptcha/core-glue": { + "version": "0.1.0-alpha-3", + "resolved": "https://registry.npmjs.org/@mcaptcha/core-glue/-/core-glue-0.1.0-alpha-3.tgz", + "integrity": "sha512-avphBVgf3PPDWuUoDsB2qiXAss2pc00lUILswJaMQofr8FQyflzkhha8H2Z+qGFiX0Iib/yyP2TOtBDbHqE9Tg==" + }, + "@mcaptcha/vanilla-glue": { + "version": "0.1.0-alpha-1", + "resolved": "https://registry.npmjs.org/@mcaptcha/vanilla-glue/-/vanilla-glue-0.1.0-alpha-1.tgz", + "integrity": "sha512-GHPjUpqdgk9DquGnGYGDQertcwMENKUc4yr/Q3M7WzL6rPBs6JMCVdDHV22RGTxk3xBM19fGuDQ8GOyNauQ3hg==", + "requires": { + "@mcaptcha/core-glue": "^0.1.0-alpha-3" + } + }, "@nodelib/fs.scandir": { "version": "2.1.5", "resolved": "https://registry.npmjs.org/@nodelib/fs.scandir/-/fs.scandir-2.1.5.tgz", diff --git a/package.json b/package.json index c1ecd163432a8..ddbbbdc5ecaac 100644 --- a/package.json +++ b/package.json @@ -8,6 +8,7 @@ }, "dependencies": { "@claviska/jquery-minicolors": "2.3.6", + "@mcaptcha/vanilla-glue": "0.1.0-alpha-1", "@primer/octicons": "17.3.0", "add-asset-webpack-plugin": "2.0.1", "css-loader": "6.7.1", diff --git a/routers/web/auth/auth.go b/routers/web/auth/auth.go index 610e4d29045d6..08d9d4a72dbf1 100644 --- a/routers/web/auth/auth.go +++ b/routers/web/auth/auth.go @@ -414,6 +414,8 @@ func SignUp(ctx *context.Context) { ctx.Data["CaptchaType"] = setting.Service.CaptchaType ctx.Data["RecaptchaSitekey"] = setting.Service.RecaptchaSitekey ctx.Data["HcaptchaSitekey"] = setting.Service.HcaptchaSitekey + ctx.Data["McaptchaSitekey"] = setting.Service.McaptchaSitekey + ctx.Data["McaptchaURL"] = setting.Service.McaptchaURL ctx.Data["PageIsSignUp"] = true // Show Disabled Registration message if DisableRegistration or AllowOnlyExternalRegistration options are true @@ -435,6 +437,8 @@ func SignUpPost(ctx *context.Context) { ctx.Data["CaptchaType"] = setting.Service.CaptchaType ctx.Data["RecaptchaSitekey"] = setting.Service.RecaptchaSitekey ctx.Data["HcaptchaSitekey"] = setting.Service.HcaptchaSitekey + ctx.Data["McaptchaSitekey"] = setting.Service.McaptchaSitekey + ctx.Data["McaptchaURL"] = setting.Service.McaptchaURL ctx.Data["PageIsSignUp"] = true // Permission denied if DisableRegistration or AllowOnlyExternalRegistration options are true diff --git a/routers/web/auth/linkaccount.go b/routers/web/auth/linkaccount.go index a2d76e9c5a34e..0dd428ec5320c 100644 --- a/routers/web/auth/linkaccount.go +++ b/routers/web/auth/linkaccount.go @@ -40,6 +40,8 @@ func LinkAccount(ctx *context.Context) { ctx.Data["RecaptchaURL"] = setting.Service.RecaptchaURL ctx.Data["RecaptchaSitekey"] = setting.Service.RecaptchaSitekey ctx.Data["HcaptchaSitekey"] = setting.Service.HcaptchaSitekey + ctx.Data["McaptchaSitekey"] = setting.Service.McaptchaSitekey + ctx.Data["McaptchaURL"] = setting.Service.McaptchaURL ctx.Data["DisableRegistration"] = setting.Service.DisableRegistration ctx.Data["AllowOnlyInternalRegistration"] = setting.Service.AllowOnlyInternalRegistration ctx.Data["ShowRegistrationButton"] = false @@ -96,6 +98,8 @@ func LinkAccountPostSignIn(ctx *context.Context) { ctx.Data["CaptchaType"] = setting.Service.CaptchaType ctx.Data["RecaptchaSitekey"] = setting.Service.RecaptchaSitekey ctx.Data["HcaptchaSitekey"] = setting.Service.HcaptchaSitekey + ctx.Data["McaptchaSitekey"] = setting.Service.McaptchaSitekey + ctx.Data["McaptchaURL"] = setting.Service.McaptchaURL ctx.Data["DisableRegistration"] = setting.Service.DisableRegistration ctx.Data["ShowRegistrationButton"] = false @@ -195,6 +199,8 @@ func LinkAccountPostRegister(ctx *context.Context) { ctx.Data["CaptchaType"] = setting.Service.CaptchaType ctx.Data["RecaptchaSitekey"] = setting.Service.RecaptchaSitekey ctx.Data["HcaptchaSitekey"] = setting.Service.HcaptchaSitekey + ctx.Data["McaptchaSitekey"] = setting.Service.McaptchaSitekey + ctx.Data["McaptchaURL"] = setting.Service.McaptchaURL ctx.Data["DisableRegistration"] = setting.Service.DisableRegistration ctx.Data["ShowRegistrationButton"] = false diff --git a/routers/web/auth/openid.go b/routers/web/auth/openid.go index 32ae91da47b84..0c19e25cbaa63 100644 --- a/routers/web/auth/openid.go +++ b/routers/web/auth/openid.go @@ -341,6 +341,8 @@ func RegisterOpenID(ctx *context.Context) { ctx.Data["RecaptchaSitekey"] = setting.Service.RecaptchaSitekey ctx.Data["HcaptchaSitekey"] = setting.Service.HcaptchaSitekey ctx.Data["RecaptchaURL"] = setting.Service.RecaptchaURL + ctx.Data["McaptchaSitekey"] = setting.Service.McaptchaSitekey + ctx.Data["McaptchaURL"] = setting.Service.McaptchaURL ctx.Data["OpenID"] = oid userName, _ := ctx.Session.Get("openid_determined_username").(string) if userName != "" { @@ -372,6 +374,8 @@ func RegisterOpenIDPost(ctx *context.Context) { ctx.Data["CaptchaType"] = setting.Service.CaptchaType ctx.Data["RecaptchaSitekey"] = setting.Service.RecaptchaSitekey ctx.Data["HcaptchaSitekey"] = setting.Service.HcaptchaSitekey + ctx.Data["McaptchaSitekey"] = setting.Service.McaptchaSitekey + ctx.Data["McaptchaURL"] = setting.Service.McaptchaURL ctx.Data["OpenID"] = oid if setting.Service.AllowOnlyInternalRegistration { diff --git a/templates/user/auth/signup_inner.tmpl b/templates/user/auth/signup_inner.tmpl index 356c3e1cdcfc2..6ed01c19e43fc 100644 --- a/templates/user/auth/signup_inner.tmpl +++ b/templates/user/auth/signup_inner.tmpl @@ -54,6 +54,14 @@
{{end}} + {{if and .EnableCaptcha (eq .CaptchaType "mcaptcha")}} +
+ +
+
+
+ {{end}} +
diff --git a/templates/user/auth/signup_openid_register.tmpl b/templates/user/auth/signup_openid_register.tmpl index 5edd7966ffa0c..9e66fc788ba06 100644 --- a/templates/user/auth/signup_openid_register.tmpl +++ b/templates/user/auth/signup_openid_register.tmpl @@ -40,6 +40,11 @@
{{end}} + {{if and .EnableCaptcha (eq .CaptchaType "mcaptcha")}} +
+
+
+ {{end}}
diff --git a/web_src/js/features/mcaptcha.js b/web_src/js/features/mcaptcha.js new file mode 100644 index 0000000000000..fbe1885bbe9b6 --- /dev/null +++ b/web_src/js/features/mcaptcha.js @@ -0,0 +1,15 @@ +export async function initMcaptcha() { + const siteKeyEl = document.querySelector('.m-captcha'); + + if (!siteKeyEl) { + return; + } + const {default: mCaptcha} = await import(/* webpackChunkName: "mcaptcha-vanilla-glue" */'@mcaptcha/vanilla-glue'); + const siteKey = siteKeyEl.getAttribute('data-sitekey'); + mCaptcha.default({ + siteKey: { + instanceUrl: new URL('http://localhost:7000'), + key: siteKey, + } + }); +} diff --git a/web_src/js/index.js b/web_src/js/index.js index 6f872b5353378..61d81444ba8cf 100644 --- a/web_src/js/index.js +++ b/web_src/js/index.js @@ -86,6 +86,7 @@ import {initCommonOrganization} from './features/common-organization.js'; import {initRepoWikiForm} from './features/repo-wiki.js'; import {initRepoCommentForm, initRepository} from './features/repo-legacy.js'; import {initFormattingReplacements} from './features/formatting.js'; +import {initMcaptcha} from './features/mcaptcha.js'; // Run time-critical code as soon as possible. This is safe to do because this // script appears at the end of and rendered HTML is accessible at that point. @@ -182,6 +183,7 @@ $(document).ready(() => { initRepository(); initCommitStatuses(); + initMcaptcha(); initUserAuthLinkAccountView(); initUserAuthOauth2(); From 62ea258e63e5c073b01a9a64ea1d1788fd15dad3 Mon Sep 17 00:00:00 2001 From: Gusted Date: Fri, 22 Jul 2022 17:00:04 +0200 Subject: [PATCH 03/14] Code-style --- web_src/js/features/mcaptcha.js | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/web_src/js/features/mcaptcha.js b/web_src/js/features/mcaptcha.js index fbe1885bbe9b6..ebd48fa420ddd 100644 --- a/web_src/js/features/mcaptcha.js +++ b/web_src/js/features/mcaptcha.js @@ -1,11 +1,12 @@ export async function initMcaptcha() { const siteKeyEl = document.querySelector('.m-captcha'); - if (!siteKeyEl) { return; } + const {default: mCaptcha} = await import(/* webpackChunkName: "mcaptcha-vanilla-glue" */'@mcaptcha/vanilla-glue'); const siteKey = siteKeyEl.getAttribute('data-sitekey'); + mCaptcha.default({ siteKey: { instanceUrl: new URL('http://localhost:7000'), From 75d079d677587a30791d43df8c367fcf57594e39 Mon Sep 17 00:00:00 2001 From: Gusted Date: Fri, 22 Jul 2022 23:20:31 +0200 Subject: [PATCH 04/14] Implement backend verification --- go.mod | 1 + go.sum | 2 ++ modules/mcaptcha/mcaptcha.go | 23 +++++++++++++++++++++++ routers/web/auth/auth.go | 3 +++ routers/web/auth/linkaccount.go | 3 +++ routers/web/auth/openid.go | 6 ++++++ services/forms/user_form.go | 1 + services/forms/user_form_auth_openid.go | 1 + web_src/js/features/mcaptcha.js | 1 + 9 files changed, 41 insertions(+) create mode 100644 modules/mcaptcha/mcaptcha.go diff --git a/go.mod b/go.mod index 78495cc6a252a..9e84859cfa894 100644 --- a/go.mod +++ b/go.mod @@ -5,6 +5,7 @@ go 1.18 require ( code.gitea.io/gitea-vet v0.2.2-0.20220122151748-48ebc902541b code.gitea.io/sdk/gitea v0.15.1 + codeberg.org/gusted/mcaptcha v0.0.0-20220722211632-55c1ffff1222 gitea.com/go-chi/binding v0.0.0-20220309004920-114340dabecb gitea.com/go-chi/cache v0.2.0 gitea.com/go-chi/captcha v0.0.0-20211013065431-70641c1a35d5 diff --git a/go.sum b/go.sum index dca68d9a8e7d8..c1d19a6b45898 100644 --- a/go.sum +++ b/go.sum @@ -62,6 +62,8 @@ code.gitea.io/gitea-vet v0.2.2-0.20220122151748-48ebc902541b/go.mod h1:zcNbT/aJE code.gitea.io/sdk/gitea v0.11.3/go.mod h1:z3uwDV/b9Ls47NGukYM9XhnHtqPh/J+t40lsUrR6JDY= code.gitea.io/sdk/gitea v0.15.1 h1:WJreC7YYuxbn0UDaPuWIe/mtiNKTvLN8MLkaw71yx/M= code.gitea.io/sdk/gitea v0.15.1/go.mod h1:klY2LVI3s3NChzIk/MzMn7G1FHrfU7qd63iSMVoHRBA= +codeberg.org/gusted/mcaptcha v0.0.0-20220722211632-55c1ffff1222 h1:PCW4i+gnQ9XxF8V+nBch3KWdGe4MiP3xXUCA/z0jhHk= +codeberg.org/gusted/mcaptcha v0.0.0-20220722211632-55c1ffff1222/go.mod h1:IIAjsijsd8q1isWX8MACefDEgTQslQ4stk2AeeTt3kM= contrib.go.opencensus.io/exporter/aws v0.0.0-20181029163544-2befc13012d0/go.mod h1:uu1P0UCM/6RbsMrgPa98ll8ZcHM858i/AD06a9aLRCA= contrib.go.opencensus.io/exporter/ocagent v0.5.0/go.mod h1:ImxhfLRpxoYiSq891pBrLVhN+qmP8BTVvdH2YLs7Gl0= contrib.go.opencensus.io/exporter/stackdriver v0.12.1/go.mod h1:iwB6wGarfphGGe/e5CWqyUk/cLzKnWsOKPVW3no6OTw= diff --git a/modules/mcaptcha/mcaptcha.go b/modules/mcaptcha/mcaptcha.go new file mode 100644 index 0000000000000..196d74a58cc8d --- /dev/null +++ b/modules/mcaptcha/mcaptcha.go @@ -0,0 +1,23 @@ +package mcaptcha + +import ( + "context" + "fmt" + + "code.gitea.io/gitea/modules/setting" + + "codeberg.org/gusted/mcaptcha" +) + +func Verify(ctx context.Context, token string) (bool, error) { + valid, err := mcaptcha.Verify(ctx, &mcaptcha.VerifyOpts{ + InstanceURL: setting.Service.McaptchaURL, + Sitekey: setting.Service.McaptchaSitekey, + Secret: setting.Service.McaptchaSecret, + Token: token, + }) + if err != nil { + return false, fmt.Errorf("wasn't able to verify mCaptcha: %v", err) + } + return valid, nil +} diff --git a/routers/web/auth/auth.go b/routers/web/auth/auth.go index 08d9d4a72dbf1..8a4c12d57b573 100644 --- a/routers/web/auth/auth.go +++ b/routers/web/auth/auth.go @@ -18,6 +18,7 @@ import ( "code.gitea.io/gitea/modules/eventsource" "code.gitea.io/gitea/modules/hcaptcha" "code.gitea.io/gitea/modules/log" + "code.gitea.io/gitea/modules/mcaptcha" "code.gitea.io/gitea/modules/password" "code.gitea.io/gitea/modules/recaptcha" "code.gitea.io/gitea/modules/session" @@ -462,6 +463,8 @@ func SignUpPost(ctx *context.Context) { valid, err = recaptcha.Verify(ctx, form.GRecaptchaResponse) case setting.HCaptcha: valid, err = hcaptcha.Verify(ctx, form.HcaptchaResponse) + case setting.MCaptcha: + valid, err = mcaptcha.Verify(ctx, form.McaptchaResponse) default: ctx.ServerError("Unknown Captcha Type", fmt.Errorf("Unknown Captcha Type: %s", setting.Service.CaptchaType)) return diff --git a/routers/web/auth/linkaccount.go b/routers/web/auth/linkaccount.go index 0dd428ec5320c..4f3f2062b6896 100644 --- a/routers/web/auth/linkaccount.go +++ b/routers/web/auth/linkaccount.go @@ -16,6 +16,7 @@ import ( "code.gitea.io/gitea/modules/context" "code.gitea.io/gitea/modules/hcaptcha" "code.gitea.io/gitea/modules/log" + "code.gitea.io/gitea/modules/mcaptcha" "code.gitea.io/gitea/modules/recaptcha" "code.gitea.io/gitea/modules/session" "code.gitea.io/gitea/modules/setting" @@ -239,6 +240,8 @@ func LinkAccountPostRegister(ctx *context.Context) { valid, err = recaptcha.Verify(ctx, form.GRecaptchaResponse) case setting.HCaptcha: valid, err = hcaptcha.Verify(ctx, form.HcaptchaResponse) + case setting.MCaptcha: + valid, err = mcaptcha.Verify(ctx, form.McaptchaResponse) default: ctx.ServerError("Unknown Captcha Type", fmt.Errorf("Unknown Captcha Type: %s", setting.Service.CaptchaType)) return diff --git a/routers/web/auth/openid.go b/routers/web/auth/openid.go index 0c19e25cbaa63..3ffa57f8647ba 100644 --- a/routers/web/auth/openid.go +++ b/routers/web/auth/openid.go @@ -401,6 +401,12 @@ func RegisterOpenIDPost(ctx *context.Context) { return } valid, err = hcaptcha.Verify(ctx, form.HcaptchaResponse) + case setting.MCaptcha: + if err := ctx.Req.ParseForm(); err != nil { + ctx.ServerError("", err) + return + } + valid, err = hcaptcha.Verify(ctx, form.HcaptchaResponse) default: ctx.ServerError("Unknown Captcha Type", fmt.Errorf("Unknown Captcha Type: %s", setting.Service.CaptchaType)) return diff --git a/services/forms/user_form.go b/services/forms/user_form.go index 405b4a9a490f2..d0bc408490252 100644 --- a/services/forms/user_form.go +++ b/services/forms/user_form.go @@ -95,6 +95,7 @@ type RegisterForm struct { Retype string GRecaptchaResponse string `form:"g-recaptcha-response"` HcaptchaResponse string `form:"h-captcha-response"` + McaptchaResponse string `form:"m-captcha-response"` } // Validate validates the fields diff --git a/services/forms/user_form_auth_openid.go b/services/forms/user_form_auth_openid.go index fd3368d303a90..992517f34f0f0 100644 --- a/services/forms/user_form_auth_openid.go +++ b/services/forms/user_form_auth_openid.go @@ -31,6 +31,7 @@ type SignUpOpenIDForm struct { Email string `binding:"Required;Email;MaxSize(254)"` GRecaptchaResponse string `form:"g-recaptcha-response"` HcaptchaResponse string `form:"h-captcha-response"` + McaptchaResponse string `form:"m-captcha-response"` } // Validate validates the fields diff --git a/web_src/js/features/mcaptcha.js b/web_src/js/features/mcaptcha.js index ebd48fa420ddd..91261572e1a17 100644 --- a/web_src/js/features/mcaptcha.js +++ b/web_src/js/features/mcaptcha.js @@ -5,6 +5,7 @@ export async function initMcaptcha() { } const {default: mCaptcha} = await import(/* webpackChunkName: "mcaptcha-vanilla-glue" */'@mcaptcha/vanilla-glue'); + mCaptcha.INPUT_NAME = 'm-captcha-response'; const siteKey = siteKeyEl.getAttribute('data-sitekey'); mCaptcha.default({ From 614ad0bfe1ae9d29da5f97072466c2b55308dfff Mon Sep 17 00:00:00 2001 From: Gusted Date: Sat, 23 Jul 2022 00:09:39 +0200 Subject: [PATCH 05/14] Add copyright text --- modules/mcaptcha/mcaptcha.go | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/modules/mcaptcha/mcaptcha.go b/modules/mcaptcha/mcaptcha.go index 196d74a58cc8d..b889cf423b639 100644 --- a/modules/mcaptcha/mcaptcha.go +++ b/modules/mcaptcha/mcaptcha.go @@ -1,3 +1,7 @@ +// Copyright 2022 The Gitea Authors. All rights reserved. +// Use of this source code is governed by a MIT-style +// license that can be found in the LICENSE file. + package mcaptcha import ( From 5015c38cdd5cc7aaef6073bcefc6542d6cd99aa7 Mon Sep 17 00:00:00 2001 From: Gusted Date: Sat, 23 Jul 2022 06:02:20 +0200 Subject: [PATCH 06/14] Don't use hardcoded instance --- templates/user/auth/signup_inner.tmpl | 2 +- templates/user/auth/signup_openid_register.tmpl | 2 +- web_src/js/features/mcaptcha.js | 9 +++++---- 3 files changed, 7 insertions(+), 6 deletions(-) diff --git a/templates/user/auth/signup_inner.tmpl b/templates/user/auth/signup_inner.tmpl index 6ed01c19e43fc..fd98851b6b9ef 100644 --- a/templates/user/auth/signup_inner.tmpl +++ b/templates/user/auth/signup_inner.tmpl @@ -58,7 +58,7 @@
-
+
{{end}} diff --git a/templates/user/auth/signup_openid_register.tmpl b/templates/user/auth/signup_openid_register.tmpl index 9e66fc788ba06..9fe0a9de1bcbc 100644 --- a/templates/user/auth/signup_openid_register.tmpl +++ b/templates/user/auth/signup_openid_register.tmpl @@ -42,7 +42,7 @@ {{end}} {{if and .EnableCaptcha (eq .CaptchaType "mcaptcha")}}
-
+
{{end}}
diff --git a/web_src/js/features/mcaptcha.js b/web_src/js/features/mcaptcha.js index 91261572e1a17..a413408b3d94f 100644 --- a/web_src/js/features/mcaptcha.js +++ b/web_src/js/features/mcaptcha.js @@ -1,16 +1,17 @@ export async function initMcaptcha() { - const siteKeyEl = document.querySelector('.m-captcha'); - if (!siteKeyEl) { + const mCaptchaEl = document.querySelector('.m-captcha'); + if (!mCaptchaEl) { return; } const {default: mCaptcha} = await import(/* webpackChunkName: "mcaptcha-vanilla-glue" */'@mcaptcha/vanilla-glue'); mCaptcha.INPUT_NAME = 'm-captcha-response'; - const siteKey = siteKeyEl.getAttribute('data-sitekey'); + const siteKey = mCaptchaEl.getAttribute('data-sitekey'); + const instanceURL = mCaptchaEl.getAttribute('data-instance-url'); mCaptcha.default({ siteKey: { - instanceUrl: new URL('http://localhost:7000'), + instanceUrl: new URL(instanceURL), key: siteKey, } }); From d7c5033d2b90cd90148041956d33bde5371d9304 Mon Sep 17 00:00:00 2001 From: Gusted Date: Sat, 23 Jul 2022 21:39:56 +0000 Subject: [PATCH 07/14] Nit pick Co-authored-by: silverwind --- web_src/js/features/mcaptcha.js | 4 +--- 1 file changed, 1 insertion(+), 3 deletions(-) diff --git a/web_src/js/features/mcaptcha.js b/web_src/js/features/mcaptcha.js index a413408b3d94f..725e2e28acf11 100644 --- a/web_src/js/features/mcaptcha.js +++ b/web_src/js/features/mcaptcha.js @@ -1,8 +1,6 @@ export async function initMcaptcha() { const mCaptchaEl = document.querySelector('.m-captcha'); - if (!mCaptchaEl) { - return; - } + if (!mCaptchaEl) return; const {default: mCaptcha} = await import(/* webpackChunkName: "mcaptcha-vanilla-glue" */'@mcaptcha/vanilla-glue'); mCaptcha.INPUT_NAME = 'm-captcha-response'; From 06c6c95e80ad906e171d8f2b171e19bf29ffa90d Mon Sep 17 00:00:00 2001 From: 6543 <6543@obermui.de> Date: Tue, 26 Jul 2022 14:20:34 +0200 Subject: [PATCH 08/14] Apply suggestions from code review MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Co-authored-by: Felipe Leopoldo Sologuren GutiƩrrez --- custom/conf/app.example.ini | 2 +- routers/web/auth/openid.go | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/custom/conf/app.example.ini b/custom/conf/app.example.ini index c39a212d7e622..c69a8b15a2341 100644 --- a/custom/conf/app.example.ini +++ b/custom/conf/app.example.ini @@ -696,7 +696,7 @@ ROUTER = console ;; Enable captcha validation for registration ;ENABLE_CAPTCHA = false ;; -;; Type of captcha you want to use. Options: image, recaptcha, hcaptcha +;; Type of captcha you want to use. Options: image, recaptcha, hcaptcha, mcaptcha. ;CAPTCHA_TYPE = image ;; ;; Change this to use recaptcha.net or other recaptcha service diff --git a/routers/web/auth/openid.go b/routers/web/auth/openid.go index 3ffa57f8647ba..78681d8a20385 100644 --- a/routers/web/auth/openid.go +++ b/routers/web/auth/openid.go @@ -406,7 +406,7 @@ func RegisterOpenIDPost(ctx *context.Context) { ctx.ServerError("", err) return } - valid, err = hcaptcha.Verify(ctx, form.HcaptchaResponse) + valid, err = mcaptcha.Verify(ctx, form.McaptchaResponse) default: ctx.ServerError("Unknown Captcha Type", fmt.Errorf("Unknown Captcha Type: %s", setting.Service.CaptchaType)) return From 4c52706d759794e74e4e422bdbd49af71dad0892 Mon Sep 17 00:00:00 2001 From: 6543 <6543@obermui.de> Date: Tue, 26 Jul 2022 15:39:45 +0200 Subject: [PATCH 09/14] fix lint --- routers/web/auth/openid.go | 1 + 1 file changed, 1 insertion(+) diff --git a/routers/web/auth/openid.go b/routers/web/auth/openid.go index 78681d8a20385..3b1065189d9dc 100644 --- a/routers/web/auth/openid.go +++ b/routers/web/auth/openid.go @@ -15,6 +15,7 @@ import ( "code.gitea.io/gitea/modules/context" "code.gitea.io/gitea/modules/hcaptcha" "code.gitea.io/gitea/modules/log" + "code.gitea.io/gitea/modules/mcaptcha" "code.gitea.io/gitea/modules/recaptcha" "code.gitea.io/gitea/modules/session" "code.gitea.io/gitea/modules/setting" From 0789b3311d8ea1cdb768efa13a6ee050d76fbf1d Mon Sep 17 00:00:00 2001 From: Gusted Date: Tue, 26 Jul 2022 22:56:58 +0200 Subject: [PATCH 10/14] Hack mobile CSS together - Still requires patch on mCaptcha's side to provide good iframe settings & good CSS on widget HTML. --- templates/user/auth/signup_inner.tmpl | 6 +++--- web_src/less/helpers.less | 5 +++++ 2 files changed, 8 insertions(+), 3 deletions(-) diff --git a/templates/user/auth/signup_inner.tmpl b/templates/user/auth/signup_inner.tmpl index fd98851b6b9ef..58a8d2452a70e 100644 --- a/templates/user/auth/signup_inner.tmpl +++ b/templates/user/auth/signup_inner.tmpl @@ -55,9 +55,9 @@
{{end}} {{if and .EnableCaptcha (eq .CaptchaType "mcaptcha")}} -
- -
+
+ +
{{end}} diff --git a/web_src/less/helpers.less b/web_src/less/helpers.less index 0c4bf1753af32..f734b19f868af 100644 --- a/web_src/less/helpers.less +++ b/web_src/less/helpers.less @@ -167,3 +167,8 @@ .py-3 { padding-top: .5rem !important; padding-bottom: .5rem !important; } .py-4 { padding-top: 1rem !important; padding-bottom: 1rem !important; } .py-5 { padding-top: 2rem !important; padding-bottom: 2rem !important; } + +@media @mediaSm { + .db-small { display: block !important; } + .w-100-small { width: 100% !important; } +} From c866103203575c193fdfb3095b55a8c3a83f2073 Mon Sep 17 00:00:00 2001 From: Gusted Date: Thu, 28 Jul 2022 11:33:13 +0200 Subject: [PATCH 11/14] Update mCaptcha-glue --- package-lock.json | 14 +++++++------- package.json | 8 ++------ 2 files changed, 9 insertions(+), 13 deletions(-) diff --git a/package-lock.json b/package-lock.json index e92fde3324f45..52bcfae940f3a 100644 --- a/package-lock.json +++ b/package-lock.json @@ -8,7 +8,7 @@ "license": "MIT", "dependencies": { "@claviska/jquery-minicolors": "2.3.6", - "@mcaptcha/vanilla-glue": "0.1.0-alpha-1", + "@mcaptcha/vanilla-glue": "0.1.0-alpha-2", "@primer/octicons": "17.3.0", "add-asset-webpack-plugin": "2.0.1", "css-loader": "6.7.1", @@ -1660,9 +1660,9 @@ ] }, "node_modules/@mcaptcha/vanilla-glue": { - "version": "0.1.0-alpha-1", - "resolved": "https://registry.npmjs.org/@mcaptcha/vanilla-glue/-/vanilla-glue-0.1.0-alpha-1.tgz", - "integrity": "sha512-GHPjUpqdgk9DquGnGYGDQertcwMENKUc4yr/Q3M7WzL6rPBs6JMCVdDHV22RGTxk3xBM19fGuDQ8GOyNauQ3hg==", + "version": "0.1.0-alpha-2", + "resolved": "https://registry.npmjs.org/@mcaptcha/vanilla-glue/-/vanilla-glue-0.1.0-alpha-2.tgz", + "integrity": "sha512-cQOg3EIhdjk1xoZtjD9SVPwQAnd49FCvHKchwFZZuhdNTeFs7SUHynOCekuGow2Ip0RJZuMZGcRxvWMgd0ogng==", "funding": [ { "type": "individual", @@ -13848,9 +13848,9 @@ "integrity": "sha512-avphBVgf3PPDWuUoDsB2qiXAss2pc00lUILswJaMQofr8FQyflzkhha8H2Z+qGFiX0Iib/yyP2TOtBDbHqE9Tg==" }, "@mcaptcha/vanilla-glue": { - "version": "0.1.0-alpha-1", - "resolved": "https://registry.npmjs.org/@mcaptcha/vanilla-glue/-/vanilla-glue-0.1.0-alpha-1.tgz", - "integrity": "sha512-GHPjUpqdgk9DquGnGYGDQertcwMENKUc4yr/Q3M7WzL6rPBs6JMCVdDHV22RGTxk3xBM19fGuDQ8GOyNauQ3hg==", + "version": "0.1.0-alpha-2", + "resolved": "https://registry.npmjs.org/@mcaptcha/vanilla-glue/-/vanilla-glue-0.1.0-alpha-2.tgz", + "integrity": "sha512-cQOg3EIhdjk1xoZtjD9SVPwQAnd49FCvHKchwFZZuhdNTeFs7SUHynOCekuGow2Ip0RJZuMZGcRxvWMgd0ogng==", "requires": { "@mcaptcha/core-glue": "^0.1.0-alpha-3" } diff --git a/package.json b/package.json index 361aafe7d91a4..40d7c51109e97 100644 --- a/package.json +++ b/package.json @@ -8,7 +8,7 @@ }, "dependencies": { "@claviska/jquery-minicolors": "2.3.6", - "@mcaptcha/vanilla-glue": "0.1.0-alpha-1", + "@mcaptcha/vanilla-glue": "0.1.0-alpha-2", "@primer/octicons": "17.3.0", "add-asset-webpack-plugin": "2.0.1", "css-loader": "6.7.1", @@ -62,9 +62,5 @@ "svgo": "2.8.0", "updates": "13.1.2" }, - "browserslist": [ - "defaults", - "not ie > 0", - "not ie_mob > 0" - ] + "browserslist": ["defaults", "not ie > 0", "not ie_mob > 0"] } From f4e417b2ff32f199b4ae2a47330cc9aca64eb012 Mon Sep 17 00:00:00 2001 From: Gusted Date: Fri, 29 Jul 2022 20:57:10 +0200 Subject: [PATCH 12/14] Use `` instead of `
{{end}} {{if and .EnableCaptcha (eq .CaptchaType "mcaptcha")}} -
- +
+ {{.locale.Tr "captcha"}}
diff --git a/web_src/less/_form.less b/web_src/less/_form.less index eeab07c475028..c958763216669 100644 --- a/web_src/less/_form.less +++ b/web_src/less/_form.less @@ -156,7 +156,8 @@ textarea:focus, padding-left: @create-page-form-input-padding+30px; } - .inline.field > label { + .inline.field > label, + .inline.field > span { text-align: right; width: @create-page-form-input-padding; word-wrap: break-word; From 559cf0da2b997e3e5e86ef327f6e648fdb1d97ad Mon Sep 17 00:00:00 2001 From: Gusted Date: Wed, 3 Aug 2022 05:20:11 +0200 Subject: [PATCH 13/14] Fix incorrect formatting --- package.json | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/package.json b/package.json index bd2c7ef534124..1378e369b6933 100644 --- a/package.json +++ b/package.json @@ -63,5 +63,9 @@ "svgo": "2.8.0", "updates": "13.1.2" }, - "browserslist": ["defaults", "not ie > 0", "not ie_mob > 0"] + "browserslist": [ + "defaults", + "not ie > 0", + "not ie_mob > 0" + ] } From 540ae07d96e6261f1cc19d7843f00dacff7a9466 Mon Sep 17 00:00:00 2001 From: Gusted Date: Tue, 9 Aug 2022 21:44:31 +0200 Subject: [PATCH 14/14] Fix borked package-lock.json --- package-lock.json | 441 ++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 441 insertions(+) diff --git a/package-lock.json b/package-lock.json index 833b2b8295bfe..aabbd84fd9bc9 100644 --- a/package-lock.json +++ b/package-lock.json @@ -712,6 +712,21 @@ "node": ">=10.0.0" } }, + "node_modules/@esbuild/linux-loong64": { + "version": "0.14.53", + "resolved": "https://registry.npmjs.org/@esbuild/linux-loong64/-/linux-loong64-0.14.53.tgz", + "integrity": "sha512-W2dAL6Bnyn4xa/QRSU3ilIK4EzD5wgYXKXJiS1HDF5vU3675qc2bvFyLwbUcdmssDveyndy7FbitrCoiV/eMLg==", + "cpu": [ + "loong64" + ], + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">=12" + } + }, "node_modules/@eslint/eslintrc": { "version": "1.3.0", "resolved": "https://registry.npmjs.org/@eslint/eslintrc/-/eslintrc-1.3.0.tgz", @@ -5030,6 +5045,111 @@ "esbuild-windows-arm64": "0.14.53" } }, + "node_modules/esbuild-android-64": { + "version": "0.14.53", + "resolved": "https://registry.npmjs.org/esbuild-android-64/-/esbuild-android-64-0.14.53.tgz", + "integrity": "sha512-fIL93sOTnEU+NrTAVMIKiAw0YH22HWCAgg4N4Z6zov2t0kY9RAJ50zY9ZMCQ+RT6bnOfDt8gCTnt/RaSNA2yRA==", + "cpu": [ + "x64" + ], + "optional": true, + "os": [ + "android" + ], + "engines": { + "node": ">=12" + } + }, + "node_modules/esbuild-android-arm64": { + "version": "0.14.53", + "resolved": "https://registry.npmjs.org/esbuild-android-arm64/-/esbuild-android-arm64-0.14.53.tgz", + "integrity": "sha512-PC7KaF1v0h/nWpvlU1UMN7dzB54cBH8qSsm7S9mkwFA1BXpaEOufCg8hdoEI1jep0KeO/rjZVWrsH8+q28T77A==", + "cpu": [ + "arm64" + ], + "optional": true, + "os": [ + "android" + ], + "engines": { + "node": ">=12" + } + }, + "node_modules/esbuild-darwin-64": { + "version": "0.14.53", + "resolved": "https://registry.npmjs.org/esbuild-darwin-64/-/esbuild-darwin-64-0.14.53.tgz", + "integrity": "sha512-gE7P5wlnkX4d4PKvLBUgmhZXvL7lzGRLri17/+CmmCzfncIgq8lOBvxGMiQ4xazplhxq+72TEohyFMZLFxuWvg==", + "cpu": [ + "x64" + ], + "optional": true, + "os": [ + "darwin" + ], + "engines": { + "node": ">=12" + } + }, + "node_modules/esbuild-darwin-arm64": { + "version": "0.14.53", + "resolved": "https://registry.npmjs.org/esbuild-darwin-arm64/-/esbuild-darwin-arm64-0.14.53.tgz", + "integrity": "sha512-otJwDU3hnI15Q98PX4MJbknSZ/WSR1I45il7gcxcECXzfN4Mrpft5hBDHXNRnCh+5858uPXBXA1Vaz2jVWLaIA==", + "cpu": [ + "arm64" + ], + "optional": true, + "os": [ + "darwin" + ], + "engines": { + "node": ">=12" + } + }, + "node_modules/esbuild-freebsd-64": { + "version": "0.14.53", + "resolved": "https://registry.npmjs.org/esbuild-freebsd-64/-/esbuild-freebsd-64-0.14.53.tgz", + "integrity": "sha512-WkdJa8iyrGHyKiPF4lk0MiOF87Q2SkE+i+8D4Cazq3/iqmGPJ6u49je300MFi5I2eUsQCkaOWhpCVQMTKGww2w==", + "cpu": [ + "x64" + ], + "optional": true, + "os": [ + "freebsd" + ], + "engines": { + "node": ">=12" + } + }, + "node_modules/esbuild-freebsd-arm64": { + "version": "0.14.53", + "resolved": "https://registry.npmjs.org/esbuild-freebsd-arm64/-/esbuild-freebsd-arm64-0.14.53.tgz", + "integrity": "sha512-9T7WwCuV30NAx0SyQpw8edbKvbKELnnm1FHg7gbSYaatH+c8WJW10g/OdM7JYnv7qkimw2ZTtSA+NokOLd2ydQ==", + "cpu": [ + "arm64" + ], + "optional": true, + "os": [ + "freebsd" + ], + "engines": { + "node": ">=12" + } + }, + "node_modules/esbuild-linux-32": { + "version": "0.14.53", + "resolved": "https://registry.npmjs.org/esbuild-linux-32/-/esbuild-linux-32-0.14.53.tgz", + "integrity": "sha512-VGanLBg5en2LfGDgLEUxQko2lqsOS7MTEWUi8x91YmsHNyzJVT/WApbFFx3MQGhkf+XdimVhpyo5/G0PBY91zg==", + "cpu": [ + "ia32" + ], + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">=12" + } + }, "node_modules/esbuild-linux-64": { "version": "0.14.53", "resolved": "https://registry.npmjs.org/esbuild-linux-64/-/esbuild-linux-64-0.14.53.tgz", @@ -5045,6 +5165,96 @@ "node": ">=12" } }, + "node_modules/esbuild-linux-arm": { + "version": "0.14.53", + "resolved": "https://registry.npmjs.org/esbuild-linux-arm/-/esbuild-linux-arm-0.14.53.tgz", + "integrity": "sha512-/u81NGAVZMopbmzd21Nu/wvnKQK3pT4CrvQ8BTje1STXcQAGnfyKgQlj3m0j2BzYbvQxSy+TMck4TNV2onvoPA==", + "cpu": [ + "arm" + ], + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">=12" + } + }, + "node_modules/esbuild-linux-arm64": { + "version": "0.14.53", + "resolved": "https://registry.npmjs.org/esbuild-linux-arm64/-/esbuild-linux-arm64-0.14.53.tgz", + "integrity": "sha512-GDmWITT+PMsjCA6/lByYk7NyFssW4Q6in32iPkpjZ/ytSyH+xeEx8q7HG3AhWH6heemEYEWpTll/eui3jwlSnw==", + "cpu": [ + "arm64" + ], + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">=12" + } + }, + "node_modules/esbuild-linux-mips64le": { + "version": "0.14.53", + "resolved": "https://registry.npmjs.org/esbuild-linux-mips64le/-/esbuild-linux-mips64le-0.14.53.tgz", + "integrity": "sha512-d6/XHIQW714gSSp6tOOX2UscedVobELvQlPMkInhx1NPz4ThZI9uNLQ4qQJHGBGKGfu+rtJsxM4NVHLhnNRdWQ==", + "cpu": [ + "mips64el" + ], + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">=12" + } + }, + "node_modules/esbuild-linux-ppc64le": { + "version": "0.14.53", + "resolved": "https://registry.npmjs.org/esbuild-linux-ppc64le/-/esbuild-linux-ppc64le-0.14.53.tgz", + "integrity": "sha512-ndnJmniKPCB52m+r6BtHHLAOXw+xBCWIxNnedbIpuREOcbSU/AlyM/2dA3BmUQhsHdb4w3amD5U2s91TJ3MzzA==", + "cpu": [ + "ppc64" + ], + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">=12" + } + }, + "node_modules/esbuild-linux-riscv64": { + "version": "0.14.53", + "resolved": "https://registry.npmjs.org/esbuild-linux-riscv64/-/esbuild-linux-riscv64-0.14.53.tgz", + "integrity": "sha512-yG2sVH+QSix6ct4lIzJj329iJF3MhloLE6/vKMQAAd26UVPVkhMFqFopY+9kCgYsdeWvXdPgmyOuKa48Y7+/EQ==", + "cpu": [ + "riscv64" + ], + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">=12" + } + }, + "node_modules/esbuild-linux-s390x": { + "version": "0.14.53", + "resolved": "https://registry.npmjs.org/esbuild-linux-s390x/-/esbuild-linux-s390x-0.14.53.tgz", + "integrity": "sha512-OCJlgdkB+XPYndHmw6uZT7jcYgzmx9K+28PVdOa/eLjdoYkeAFvH5hTwX4AXGLZLH09tpl4bVsEtvuyUldaNCg==", + "cpu": [ + "s390x" + ], + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">=12" + } + }, "node_modules/esbuild-loader": { "version": "2.19.0", "resolved": "https://registry.npmjs.org/esbuild-loader/-/esbuild-loader-2.19.0.tgz", @@ -5064,6 +5274,96 @@ "webpack": "^4.40.0 || ^5.0.0" } }, + "node_modules/esbuild-netbsd-64": { + "version": "0.14.53", + "resolved": "https://registry.npmjs.org/esbuild-netbsd-64/-/esbuild-netbsd-64-0.14.53.tgz", + "integrity": "sha512-gp2SB+Efc7MhMdWV2+pmIs/Ja/Mi5rjw+wlDmmbIn68VGXBleNgiEZG+eV2SRS0kJEUyHNedDtwRIMzaohWedQ==", + "cpu": [ + "x64" + ], + "optional": true, + "os": [ + "netbsd" + ], + "engines": { + "node": ">=12" + } + }, + "node_modules/esbuild-openbsd-64": { + "version": "0.14.53", + "resolved": "https://registry.npmjs.org/esbuild-openbsd-64/-/esbuild-openbsd-64-0.14.53.tgz", + "integrity": "sha512-eKQ30ZWe+WTZmteDYg8S+YjHV5s4iTxeSGhJKJajFfQx9TLZJvsJX0/paqwP51GicOUruFpSUAs2NCc0a4ivQQ==", + "cpu": [ + "x64" + ], + "optional": true, + "os": [ + "openbsd" + ], + "engines": { + "node": ">=12" + } + }, + "node_modules/esbuild-sunos-64": { + "version": "0.14.53", + "resolved": "https://registry.npmjs.org/esbuild-sunos-64/-/esbuild-sunos-64-0.14.53.tgz", + "integrity": "sha512-OWLpS7a2FrIRukQqcgQqR1XKn0jSJoOdT+RlhAxUoEQM/IpytS3FXzCJM6xjUYtpO5GMY0EdZJp+ur2pYdm39g==", + "cpu": [ + "x64" + ], + "optional": true, + "os": [ + "sunos" + ], + "engines": { + "node": ">=12" + } + }, + "node_modules/esbuild-windows-32": { + "version": "0.14.53", + "resolved": "https://registry.npmjs.org/esbuild-windows-32/-/esbuild-windows-32-0.14.53.tgz", + "integrity": "sha512-m14XyWQP5rwGW0tbEfp95U6A0wY0DYPInWBB7D69FAXUpBpBObRoGTKRv36lf2RWOdE4YO3TNvj37zhXjVL5xg==", + "cpu": [ + "ia32" + ], + "optional": true, + "os": [ + "win32" + ], + "engines": { + "node": ">=12" + } + }, + "node_modules/esbuild-windows-64": { + "version": "0.14.53", + "resolved": "https://registry.npmjs.org/esbuild-windows-64/-/esbuild-windows-64-0.14.53.tgz", + "integrity": "sha512-s9skQFF0I7zqnQ2K8S1xdLSfZFsPLuOGmSx57h2btSEswv0N0YodYvqLcJMrNMXh6EynOmWD7rz+0rWWbFpIHQ==", + "cpu": [ + "x64" + ], + "optional": true, + "os": [ + "win32" + ], + "engines": { + "node": ">=12" + } + }, + "node_modules/esbuild-windows-arm64": { + "version": "0.14.53", + "resolved": "https://registry.npmjs.org/esbuild-windows-arm64/-/esbuild-windows-arm64-0.14.53.tgz", + "integrity": "sha512-E+5Gvb+ZWts+00T9II6wp2L3KG2r3iGxByqd/a1RmLmYWVsSVUjkvIxZuJ3hYTIbhLkH5PRwpldGTKYqVz0nzQ==", + "cpu": [ + "arm64" + ], + "optional": true, + "os": [ + "win32" + ], + "engines": { + "node": ">=12" + } + }, "node_modules/escalade": { "version": "3.1.1", "resolved": "https://registry.npmjs.org/escalade/-/escalade-3.1.1.tgz", @@ -5936,6 +6236,20 @@ "resolved": "https://registry.npmjs.org/fs.realpath/-/fs.realpath-1.0.0.tgz", "integrity": "sha512-OO0pH2lK6a0hZnAdau5ItzHPI6pUlvI7jMVnxUQRtw4owF2wk8lOSabtGDCTP4Ggrg2MbGnWO9X8K1t4+fGMDw==" }, + "node_modules/fsevents": { + "version": "2.3.2", + "resolved": "https://registry.npmjs.org/fsevents/-/fsevents-2.3.2.tgz", + "integrity": "sha512-xiqMQR4xAeHTuB9uWm+fFRcIOgKBMiOBP+eXiyT7jsgVCq1bkVygt00oASowB7EdtpOHaaPgKt812P9ab+DDKA==", + "dev": true, + "hasInstallScript": true, + "optional": true, + "os": [ + "darwin" + ], + "engines": { + "node": "^8.16.0 || ^10.6.0 || >=11.0.0" + } + }, "node_modules/ftp": { "version": "0.3.10", "resolved": "https://registry.npmjs.org/ftp/-/ftp-0.3.10.tgz", @@ -13095,6 +13409,12 @@ "resolved": "https://registry.npmjs.org/@discoveryjs/json-ext/-/json-ext-0.5.7.tgz", "integrity": "sha512-dBVuXR082gk3jsFp7Rd/JI4kytwGHecnCoTtXFb7DB6CNHp4rg5k1bhg0nWdLGLnOV71lmDzGQaLMy8iPLY0pw==" }, + "@esbuild/linux-loong64": { + "version": "0.14.53", + "resolved": "https://registry.npmjs.org/@esbuild/linux-loong64/-/linux-loong64-0.14.53.tgz", + "integrity": "sha512-W2dAL6Bnyn4xa/QRSU3ilIK4EzD5wgYXKXJiS1HDF5vU3675qc2bvFyLwbUcdmssDveyndy7FbitrCoiV/eMLg==", + "optional": true + }, "@eslint/eslintrc": { "version": "1.3.0", "resolved": "https://registry.npmjs.org/@eslint/eslintrc/-/eslintrc-1.3.0.tgz", @@ -16576,12 +16896,90 @@ "esbuild-windows-arm64": "0.14.53" } }, + "esbuild-android-64": { + "version": "0.14.53", + "resolved": "https://registry.npmjs.org/esbuild-android-64/-/esbuild-android-64-0.14.53.tgz", + "integrity": "sha512-fIL93sOTnEU+NrTAVMIKiAw0YH22HWCAgg4N4Z6zov2t0kY9RAJ50zY9ZMCQ+RT6bnOfDt8gCTnt/RaSNA2yRA==", + "optional": true + }, + "esbuild-android-arm64": { + "version": "0.14.53", + "resolved": "https://registry.npmjs.org/esbuild-android-arm64/-/esbuild-android-arm64-0.14.53.tgz", + "integrity": "sha512-PC7KaF1v0h/nWpvlU1UMN7dzB54cBH8qSsm7S9mkwFA1BXpaEOufCg8hdoEI1jep0KeO/rjZVWrsH8+q28T77A==", + "optional": true + }, + "esbuild-darwin-64": { + "version": "0.14.53", + "resolved": "https://registry.npmjs.org/esbuild-darwin-64/-/esbuild-darwin-64-0.14.53.tgz", + "integrity": "sha512-gE7P5wlnkX4d4PKvLBUgmhZXvL7lzGRLri17/+CmmCzfncIgq8lOBvxGMiQ4xazplhxq+72TEohyFMZLFxuWvg==", + "optional": true + }, + "esbuild-darwin-arm64": { + "version": "0.14.53", + "resolved": "https://registry.npmjs.org/esbuild-darwin-arm64/-/esbuild-darwin-arm64-0.14.53.tgz", + "integrity": "sha512-otJwDU3hnI15Q98PX4MJbknSZ/WSR1I45il7gcxcECXzfN4Mrpft5hBDHXNRnCh+5858uPXBXA1Vaz2jVWLaIA==", + "optional": true + }, + "esbuild-freebsd-64": { + "version": "0.14.53", + "resolved": "https://registry.npmjs.org/esbuild-freebsd-64/-/esbuild-freebsd-64-0.14.53.tgz", + "integrity": "sha512-WkdJa8iyrGHyKiPF4lk0MiOF87Q2SkE+i+8D4Cazq3/iqmGPJ6u49je300MFi5I2eUsQCkaOWhpCVQMTKGww2w==", + "optional": true + }, + "esbuild-freebsd-arm64": { + "version": "0.14.53", + "resolved": "https://registry.npmjs.org/esbuild-freebsd-arm64/-/esbuild-freebsd-arm64-0.14.53.tgz", + "integrity": "sha512-9T7WwCuV30NAx0SyQpw8edbKvbKELnnm1FHg7gbSYaatH+c8WJW10g/OdM7JYnv7qkimw2ZTtSA+NokOLd2ydQ==", + "optional": true + }, + "esbuild-linux-32": { + "version": "0.14.53", + "resolved": "https://registry.npmjs.org/esbuild-linux-32/-/esbuild-linux-32-0.14.53.tgz", + "integrity": "sha512-VGanLBg5en2LfGDgLEUxQko2lqsOS7MTEWUi8x91YmsHNyzJVT/WApbFFx3MQGhkf+XdimVhpyo5/G0PBY91zg==", + "optional": true + }, "esbuild-linux-64": { "version": "0.14.53", "resolved": "https://registry.npmjs.org/esbuild-linux-64/-/esbuild-linux-64-0.14.53.tgz", "integrity": "sha512-pP/FA55j/fzAV7N9DF31meAyjOH6Bjuo3aSKPh26+RW85ZEtbJv9nhoxmGTd9FOqjx59Tc1ZbrJabuiXlMwuZQ==", "optional": true }, + "esbuild-linux-arm": { + "version": "0.14.53", + "resolved": "https://registry.npmjs.org/esbuild-linux-arm/-/esbuild-linux-arm-0.14.53.tgz", + "integrity": "sha512-/u81NGAVZMopbmzd21Nu/wvnKQK3pT4CrvQ8BTje1STXcQAGnfyKgQlj3m0j2BzYbvQxSy+TMck4TNV2onvoPA==", + "optional": true + }, + "esbuild-linux-arm64": { + "version": "0.14.53", + "resolved": "https://registry.npmjs.org/esbuild-linux-arm64/-/esbuild-linux-arm64-0.14.53.tgz", + "integrity": "sha512-GDmWITT+PMsjCA6/lByYk7NyFssW4Q6in32iPkpjZ/ytSyH+xeEx8q7HG3AhWH6heemEYEWpTll/eui3jwlSnw==", + "optional": true + }, + "esbuild-linux-mips64le": { + "version": "0.14.53", + "resolved": "https://registry.npmjs.org/esbuild-linux-mips64le/-/esbuild-linux-mips64le-0.14.53.tgz", + "integrity": "sha512-d6/XHIQW714gSSp6tOOX2UscedVobELvQlPMkInhx1NPz4ThZI9uNLQ4qQJHGBGKGfu+rtJsxM4NVHLhnNRdWQ==", + "optional": true + }, + "esbuild-linux-ppc64le": { + "version": "0.14.53", + "resolved": "https://registry.npmjs.org/esbuild-linux-ppc64le/-/esbuild-linux-ppc64le-0.14.53.tgz", + "integrity": "sha512-ndnJmniKPCB52m+r6BtHHLAOXw+xBCWIxNnedbIpuREOcbSU/AlyM/2dA3BmUQhsHdb4w3amD5U2s91TJ3MzzA==", + "optional": true + }, + "esbuild-linux-riscv64": { + "version": "0.14.53", + "resolved": "https://registry.npmjs.org/esbuild-linux-riscv64/-/esbuild-linux-riscv64-0.14.53.tgz", + "integrity": "sha512-yG2sVH+QSix6ct4lIzJj329iJF3MhloLE6/vKMQAAd26UVPVkhMFqFopY+9kCgYsdeWvXdPgmyOuKa48Y7+/EQ==", + "optional": true + }, + "esbuild-linux-s390x": { + "version": "0.14.53", + "resolved": "https://registry.npmjs.org/esbuild-linux-s390x/-/esbuild-linux-s390x-0.14.53.tgz", + "integrity": "sha512-OCJlgdkB+XPYndHmw6uZT7jcYgzmx9K+28PVdOa/eLjdoYkeAFvH5hTwX4AXGLZLH09tpl4bVsEtvuyUldaNCg==", + "optional": true + }, "esbuild-loader": { "version": "2.19.0", "resolved": "https://registry.npmjs.org/esbuild-loader/-/esbuild-loader-2.19.0.tgz", @@ -16595,6 +16993,42 @@ "webpack-sources": "^2.2.0" } }, + "esbuild-netbsd-64": { + "version": "0.14.53", + "resolved": "https://registry.npmjs.org/esbuild-netbsd-64/-/esbuild-netbsd-64-0.14.53.tgz", + "integrity": "sha512-gp2SB+Efc7MhMdWV2+pmIs/Ja/Mi5rjw+wlDmmbIn68VGXBleNgiEZG+eV2SRS0kJEUyHNedDtwRIMzaohWedQ==", + "optional": true + }, + "esbuild-openbsd-64": { + "version": "0.14.53", + "resolved": "https://registry.npmjs.org/esbuild-openbsd-64/-/esbuild-openbsd-64-0.14.53.tgz", + "integrity": "sha512-eKQ30ZWe+WTZmteDYg8S+YjHV5s4iTxeSGhJKJajFfQx9TLZJvsJX0/paqwP51GicOUruFpSUAs2NCc0a4ivQQ==", + "optional": true + }, + "esbuild-sunos-64": { + "version": "0.14.53", + "resolved": "https://registry.npmjs.org/esbuild-sunos-64/-/esbuild-sunos-64-0.14.53.tgz", + "integrity": "sha512-OWLpS7a2FrIRukQqcgQqR1XKn0jSJoOdT+RlhAxUoEQM/IpytS3FXzCJM6xjUYtpO5GMY0EdZJp+ur2pYdm39g==", + "optional": true + }, + "esbuild-windows-32": { + "version": "0.14.53", + "resolved": "https://registry.npmjs.org/esbuild-windows-32/-/esbuild-windows-32-0.14.53.tgz", + "integrity": "sha512-m14XyWQP5rwGW0tbEfp95U6A0wY0DYPInWBB7D69FAXUpBpBObRoGTKRv36lf2RWOdE4YO3TNvj37zhXjVL5xg==", + "optional": true + }, + "esbuild-windows-64": { + "version": "0.14.53", + "resolved": "https://registry.npmjs.org/esbuild-windows-64/-/esbuild-windows-64-0.14.53.tgz", + "integrity": "sha512-s9skQFF0I7zqnQ2K8S1xdLSfZFsPLuOGmSx57h2btSEswv0N0YodYvqLcJMrNMXh6EynOmWD7rz+0rWWbFpIHQ==", + "optional": true + }, + "esbuild-windows-arm64": { + "version": "0.14.53", + "resolved": "https://registry.npmjs.org/esbuild-windows-arm64/-/esbuild-windows-arm64-0.14.53.tgz", + "integrity": "sha512-E+5Gvb+ZWts+00T9II6wp2L3KG2r3iGxByqd/a1RmLmYWVsSVUjkvIxZuJ3hYTIbhLkH5PRwpldGTKYqVz0nzQ==", + "optional": true + }, "escalade": { "version": "3.1.1", "resolved": "https://registry.npmjs.org/escalade/-/escalade-3.1.1.tgz", @@ -17270,6 +17704,13 @@ "resolved": "https://registry.npmjs.org/fs.realpath/-/fs.realpath-1.0.0.tgz", "integrity": "sha512-OO0pH2lK6a0hZnAdau5ItzHPI6pUlvI7jMVnxUQRtw4owF2wk8lOSabtGDCTP4Ggrg2MbGnWO9X8K1t4+fGMDw==" }, + "fsevents": { + "version": "2.3.2", + "resolved": "https://registry.npmjs.org/fsevents/-/fsevents-2.3.2.tgz", + "integrity": "sha512-xiqMQR4xAeHTuB9uWm+fFRcIOgKBMiOBP+eXiyT7jsgVCq1bkVygt00oASowB7EdtpOHaaPgKt812P9ab+DDKA==", + "dev": true, + "optional": true + }, "ftp": { "version": "0.3.10", "resolved": "https://registry.npmjs.org/ftp/-/ftp-0.3.10.tgz",