signup: add reCAPTCHA

can be enabled in settings > captcha, requires a site key & secret key
from google. New wiki article explains getting these. currently a little
ugly looking on the page itself, hopefully fixable.
user-page
Harvey Tindall 1 year ago
parent 115f5ae6a3
commit 4014e93155
No known key found for this signature in database
GPG Key ID: BBC65952848FB1A2

@ -335,6 +335,41 @@
"type": "bool", "type": "bool",
"value": false, "value": false,
"description": "Enable a CAPTCHA on the account creation form." "description": "Enable a CAPTCHA on the account creation form."
},
"recaptcha": {
"name": "Use Google reCAPTCHA",
"required": false,
"requires_restart": true,
"type": "bool",
"value": false,
"description": "More reliable, but requires some setup. See jfa-go wiki for more info."
},
"recaptcha_site_key": {
"name": "reCAPTCHA Site Key",
"required": false,
"requires_restart": true,
"type": "text",
"depends_true": "recaptcha",
"value": "",
"description": "Site Key, see jfa-go wiki for how to acquire one."
},
"recaptcha_secret_key": {
"name": "reCAPTCHA Secret Key",
"required": false,
"requires_restart": true,
"type": "text",
"depends_true": "recaptcha",
"value": "",
"description": "Secret Key, see jfa-go wiki for how to acquire one."
},
"recaptcha_hostname": {
"name": "Hostname",
"required": false,
"requires_restart": true,
"type": "text",
"depends_true": "recaptcha",
"value": "",
"description": "Public host-name of jfa-go, e.g. \"site.com\". Don't include any subpaths."
} }
} }
}, },

@ -27,10 +27,23 @@
window.matrixRequired = {{ .matrixRequired }}; window.matrixRequired = {{ .matrixRequired }};
window.matrixUserID = "{{ .matrixUser }}"; window.matrixUserID = "{{ .matrixUser }}";
window.captcha = {{ .captcha }}; window.captcha = {{ .captcha }};
window.reCAPTCHA = {{ .reCAPTCHA }};
window.reCAPTCHASiteKey = "{{ .reCAPTCHASiteKey }}";
</script> </script>
{{ if .passwordReset }} {{ if .passwordReset }}
<script src="js/pwr.js" type="module"></script> <script src="js/pwr.js" type="module"></script>
{{ else }} {{ else }}
<script src="js/form.js" type="module"></script> <script src="js/form.js" type="module"></script>
{{ if .reCAPTCHA }}
<script>
var reCAPTCHACallback = () => {
const el = document.getElementsByClassName("g-recaptcha")[0];
grecaptcha.render(el, {
"sitekey": window.reCAPTCHASiteKey
});
}
</script>
<script src="https://www.google.com/recaptcha/api.js?onload=reCAPTCHACallback&render=explicit" async defer></script>
{{ end }}
{{ end }} {{ end }}
{{ end }} {{ end }}

@ -180,9 +180,11 @@
</div> </div>
{{ if .captcha }} {{ if .captcha }}
<div class="card ~neutral @low mb-4"> <div class="card ~neutral @low mb-4">
<span class="label supra mb-2">CAPTCHA <span id="captcha-regen" title="{{ .strings.refresh }}" class="badge lg @low ~info ml-2 float-right"><i class="ri-refresh-line"></i></span><span id="captcha-success" class="badge lg @low ~critical ml-2 float-right"><i class="ri-close-line"></i></span></span> <span class="label supra mb-2">CAPTCHA {{ if not .reCAPTCHA }}<span id="captcha-regen" title="{{ .strings.refresh }}" class="badge lg @low ~info ml-2 float-right"><i class="ri-refresh-line"></i></span>{{ end }}<span id="captcha-success" class="badge lg @low ~critical ml-2 float-right"><i class="ri-close-line"></i></span></span>
<div id="captcha-img" class="mt-2 mb-2"></div> <div id="captcha-img" class="mt-2 mb-2 {{ if .reCAPTCHA }}g-recaptcha{{ end }}"></div>
{{ if not .reCAPTCHA }}
<input class="field ~neutral @low" id="captcha-input" class="mt-2" placeholder="CAPTCHA"> <input class="field ~neutral @low" id="captcha-input" class="mt-2" placeholder="CAPTCHA">
{{ end }}
</div> </div>
{{ end }} {{ end }}
{{ if .contactMessage }} {{ if .contactMessage }}

@ -359,3 +359,17 @@ type genCaptchaDTO struct {
type forUserDTO struct { type forUserDTO struct {
ID string `json:"id"` // Jellyfin ID ID string `json:"id"` // Jellyfin ID
} }
// ReCaptchaRequestDTO is sent to /api/siteverify, and includes the identifier of the CAPTCHA data is requested for.
type ReCaptchaRequestDTO struct {
Secret string `json:"secret"`
Response string `json:"response"`
}
// ReCaptchaResponseDTO is returned upon POST to reCAPTCHA /api/siteverify, and gives details upon the use of a CAPTCHA.
type ReCaptchaResponseDTO struct {
Success bool `json:"success"`
ChallengeTimestamp string `json:"challenge_ts"` // ISO yyyy-MM-dd'T'HH:mm:ssZZ
Hostname string `json:"hostname"`
ErrorCodes []string `json:"error-codes"`
}

368
package-lock.json generated

@ -15,7 +15,7 @@
"any-date-parser": "^1.5.4", "any-date-parser": "^1.5.4",
"browserslist": "^4.21.7", "browserslist": "^4.21.7",
"cheerio": "^1.0.0-rc.12", "cheerio": "^1.0.0-rc.12",
"esbuild": "^0.18.2", "esbuild": "^0.18.3",
"fs-cheerio": "^3.0.0", "fs-cheerio": "^3.0.0",
"inline-source": "^8.0.2", "inline-source": "^8.0.2",
"jsdom": "^22.1.0", "jsdom": "^22.1.0",
@ -57,9 +57,9 @@
} }
}, },
"node_modules/@esbuild/android-arm": { "node_modules/@esbuild/android-arm": {
"version": "0.18.2", "version": "0.18.3",
"resolved": "https://registry.npmjs.org/@esbuild/android-arm/-/android-arm-0.18.2.tgz", "resolved": "https://registry.npmjs.org/@esbuild/android-arm/-/android-arm-0.18.3.tgz",
"integrity": "sha512-YAnQBHlY0IvYtvY0avnXjI8ywW23emEjk5XExqbFmypath+Snq9MgY1IS47rnqBKVSqnl0ElDt221ZgaeRrkXg==", "integrity": "sha512-QOn3VIlL6Qv1eHBpQB/s7simaZgGss2ASyxDOwYSLmc6vD0uuizZkuYawHmuLjWEm5wPwp0JQWhbpaYwwGevYw==",
"cpu": [ "cpu": [
"arm" "arm"
], ],
@ -72,9 +72,9 @@
} }
}, },
"node_modules/@esbuild/android-arm64": { "node_modules/@esbuild/android-arm64": {
"version": "0.18.2", "version": "0.18.3",
"resolved": "https://registry.npmjs.org/@esbuild/android-arm64/-/android-arm64-0.18.2.tgz", "resolved": "https://registry.npmjs.org/@esbuild/android-arm64/-/android-arm64-0.18.3.tgz",
"integrity": "sha512-1Y2pb0hLdmji8I0zBwNsYSDN7zJSQqufgLOuOsrrod00WEAgKywQR5MB/E046Is/YTP4bgcPS4BioaSDBaLaTg==", "integrity": "sha512-PgabCsoaEEnnOiF6rUhOBXgYoLFIrHWP6mfLOzuQ1oZ1lwBdTL0hp5ivC4K3Kvz3BD8EipjeQo6l0aty3nr4qQ==",
"cpu": [ "cpu": [
"arm64" "arm64"
], ],
@ -87,9 +87,9 @@
} }
}, },
"node_modules/@esbuild/android-x64": { "node_modules/@esbuild/android-x64": {
"version": "0.18.2", "version": "0.18.3",
"resolved": "https://registry.npmjs.org/@esbuild/android-x64/-/android-x64-0.18.2.tgz", "resolved": "https://registry.npmjs.org/@esbuild/android-x64/-/android-x64-0.18.3.tgz",
"integrity": "sha512-P047Mh3pj8uYVE3A/B3QDX6nG8dKbHLJ+48R6Y0CRXCJ5PkXJxdHOTaS8SYs6eSR3FFU6/YQ5TishQXVHX7F5A==", "integrity": "sha512-1OkJf8wNX1W5ucbp5HrK+z42b9DINb4ix59oJH/PIsh9cyFMqjgRKtCBXg0zEWhkmP1k3egdfrnS7cDTpLH43g==",
"cpu": [ "cpu": [
"x64" "x64"
], ],
@ -102,9 +102,9 @@
} }
}, },
"node_modules/@esbuild/darwin-arm64": { "node_modules/@esbuild/darwin-arm64": {
"version": "0.18.2", "version": "0.18.3",
"resolved": "https://registry.npmjs.org/@esbuild/darwin-arm64/-/darwin-arm64-0.18.2.tgz", "resolved": "https://registry.npmjs.org/@esbuild/darwin-arm64/-/darwin-arm64-0.18.3.tgz",
"integrity": "sha512-a3Rkqd0tGVYMEKNy9SstWEdeBmM60l8FVD5o4rmwHr3xO1LbLqtCJSrWGbnf37hevo6m437mURVmpEHOmkXeTA==", "integrity": "sha512-57aofORpY7wDAuMs6DeqpmgSnVfZ63RgGbR/BHdOSTqJgYvHDCMY7/o1myFntl3k0YxtLE3WAm56nMf4qy3UDw==",
"cpu": [ "cpu": [
"arm64" "arm64"
], ],
@ -117,9 +117,9 @@
} }
}, },
"node_modules/@esbuild/darwin-x64": { "node_modules/@esbuild/darwin-x64": {
"version": "0.18.2", "version": "0.18.3",
"resolved": "https://registry.npmjs.org/@esbuild/darwin-x64/-/darwin-x64-0.18.2.tgz", "resolved": "https://registry.npmjs.org/@esbuild/darwin-x64/-/darwin-x64-0.18.3.tgz",
"integrity": "sha512-cvH58adz9L10JNsIcgtkWNS/1eutjRTi3rtWz1s3ZhR64BpdmkxJBAXE/UjqybyNAWLhaN8mPJdlYI2f+tQA7g==", "integrity": "sha512-NVBqMnxT9qvgu7Z322LUDlwjh4GDk6wEePyAQnHF9noxik/WvLFmr5v3Vgz5LSvqFducLCxsdmLztKhdpFW0Gg==",
"cpu": [ "cpu": [
"x64" "x64"
], ],
@ -132,9 +132,9 @@
} }
}, },
"node_modules/@esbuild/freebsd-arm64": { "node_modules/@esbuild/freebsd-arm64": {
"version": "0.18.2", "version": "0.18.3",
"resolved": "https://registry.npmjs.org/@esbuild/freebsd-arm64/-/freebsd-arm64-0.18.2.tgz", "resolved": "https://registry.npmjs.org/@esbuild/freebsd-arm64/-/freebsd-arm64-0.18.3.tgz",
"integrity": "sha512-68rGMGUdgmq+c5IvseCMqY4yaa2CAY/DIILMBA6bEU1caISF7fXnV69B1uU4s3ERuVDcasVVwiAFyNxCtkS6Zg==", "integrity": "sha512-XiLK1AsCk2wKxN7j8h9GXXCs8FPZhp07U0rnpwRkAVSVGgLaIWYSqpTRzKjAfqJiZlp+XKo1HwsmDdICEKB3Dg==",
"cpu": [ "cpu": [
"arm64" "arm64"
], ],
@ -147,9 +147,9 @@
} }
}, },
"node_modules/@esbuild/freebsd-x64": { "node_modules/@esbuild/freebsd-x64": {
"version": "0.18.2", "version": "0.18.3",
"resolved": "https://registry.npmjs.org/@esbuild/freebsd-x64/-/freebsd-x64-0.18.2.tgz", "resolved": "https://registry.npmjs.org/@esbuild/freebsd-x64/-/freebsd-x64-0.18.3.tgz",
"integrity": "sha512-ZSR9On/rXoYuAtrXo5hYKy7OuZwKZyFh2rr6L3TX4UeR1tWLf84aLyAFt7e0tlRbh4zNgqFx+ePWmsSHw7L9Bw==", "integrity": "sha512-xyITfrF0G3l1gwR79hvNCCWKQ/16uK14xNNPFgzjbIqF4EpBvhO6l3jrWxXFUW51z6dVIl2Szh3x3uIbBWzH1Q==",
"cpu": [ "cpu": [
"x64" "x64"
], ],
@ -162,9 +162,9 @@
} }
}, },
"node_modules/@esbuild/linux-arm": { "node_modules/@esbuild/linux-arm": {
"version": "0.18.2", "version": "0.18.3",
"resolved": "https://registry.npmjs.org/@esbuild/linux-arm/-/linux-arm-0.18.2.tgz", "resolved": "https://registry.npmjs.org/@esbuild/linux-arm/-/linux-arm-0.18.3.tgz",
"integrity": "sha512-jAbA75qJ70T5AOdmw9X8675ppeRfj7j57sOypoZ4mQlfQ/LKF8eoeLzTYVo8+aqLKqeIIl0vQ4hKOB0FyG98Zg==", "integrity": "sha512-fc/T0QHMzvmnlF+kfD6bHLB8u+17gg13260p/E86yYjVoKNFjonL/+Y0GGQjMbFUas9QijqOa7pcR00a9RNkwg==",
"cpu": [ "cpu": [
"arm" "arm"
], ],
@ -177,9 +177,9 @@
} }
}, },
"node_modules/@esbuild/linux-arm64": { "node_modules/@esbuild/linux-arm64": {
"version": "0.18.2", "version": "0.18.3",
"resolved": "https://registry.npmjs.org/@esbuild/linux-arm64/-/linux-arm64-0.18.2.tgz", "resolved": "https://registry.npmjs.org/@esbuild/linux-arm64/-/linux-arm64-0.18.3.tgz",
"integrity": "sha512-DFKavAzbu/n9HXWuetxmYN10XnfzW7FgOgpcrGD8eXaiu77KdgB+OVWA83x9FtDYtsoFpfdlDuVFAQFfrhu77A==", "integrity": "sha512-lsKUYVd8L/j2uNs8dhMjMsKC5MHYh77gR9EThu7YCeeFz1XpIkx1I4a7mhoVfPS2VPVD1pMCh+PgxuAHUcEmXw==",
"cpu": [ "cpu": [
"arm64" "arm64"
], ],
@ -192,9 +192,9 @@
} }
}, },
"node_modules/@esbuild/linux-ia32": { "node_modules/@esbuild/linux-ia32": {
"version": "0.18.2", "version": "0.18.3",
"resolved": "https://registry.npmjs.org/@esbuild/linux-ia32/-/linux-ia32-0.18.2.tgz", "resolved": "https://registry.npmjs.org/@esbuild/linux-ia32/-/linux-ia32-0.18.3.tgz",
"integrity": "sha512-VEaK3Z+vJyDwwPsP0sovaEw1foDzrMs7XQNYEIFkOwMjSe2BipKRKUUyrznil0p8qqsK7U8W+T7oNqZpgdnD2Q==", "integrity": "sha512-EyfGWeOwRqK5Xj18vok0qv8IFBZ1/+hKV+cqD44oVhGsxHo9TmPtoSiDrWn8Sa2swq/VuO5Aiog6YPDj81oIkA==",
"cpu": [ "cpu": [
"ia32" "ia32"
], ],
@ -207,9 +207,9 @@
} }
}, },
"node_modules/@esbuild/linux-loong64": { "node_modules/@esbuild/linux-loong64": {
"version": "0.18.2", "version": "0.18.3",
"resolved": "https://registry.npmjs.org/@esbuild/linux-loong64/-/linux-loong64-0.18.2.tgz", "resolved": "https://registry.npmjs.org/@esbuild/linux-loong64/-/linux-loong64-0.18.3.tgz",
"integrity": "sha512-Af1uZdB0oeJo4PW67l9aw94oakSamFxhC6ltC2eDkndozd9QygVNMTF7s7uxTLjo+BJqyVqG9wjmLCYF1o4NmA==", "integrity": "sha512-PwXkcl3t0kSeYH5RuJIeh/fHOzKZd+ZdifAWzpVO+9TLWArutTFBJvOSkTZ3CcqQqNrTj1Qyo6nqE8MQj/a7cQ==",
"cpu": [ "cpu": [
"loong64" "loong64"
], ],
@ -222,9 +222,9 @@
} }
}, },
"node_modules/@esbuild/linux-mips64el": { "node_modules/@esbuild/linux-mips64el": {
"version": "0.18.2", "version": "0.18.3",
"resolved": "https://registry.npmjs.org/@esbuild/linux-mips64el/-/linux-mips64el-0.18.2.tgz", "resolved": "https://registry.npmjs.org/@esbuild/linux-mips64el/-/linux-mips64el-0.18.3.tgz",
"integrity": "sha512-WcTbt61+9dREuOFKXac4Qg+3OuRhLxPL9lmkI2P7fGuq/fWS2qq+AvGGVLMyk+OtXGDjyQolcEDeYlRoOmjRYQ==", "integrity": "sha512-CRVkkSXf5GQcq7Am2a2tdIn85oqi/bkjuPvhNqcdeTgI0xgNbqLnEPRy2AEGkRuaJWB5uCX1IC4sqnY8ET14Yg==",
"cpu": [ "cpu": [
"mips64el" "mips64el"
], ],
@ -237,9 +237,9 @@
} }
}, },
"node_modules/@esbuild/linux-ppc64": { "node_modules/@esbuild/linux-ppc64": {
"version": "0.18.2", "version": "0.18.3",
"resolved": "https://registry.npmjs.org/@esbuild/linux-ppc64/-/linux-ppc64-0.18.2.tgz", "resolved": "https://registry.npmjs.org/@esbuild/linux-ppc64/-/linux-ppc64-0.18.3.tgz",
"integrity": "sha512-Ov+VHayvCPb52axma6+xm8QDawRjwHscPXedHg4U92DxlhKQ0H+6onRiC3J9kKI50p8pKKypprpCWrRrXjZN7Q==", "integrity": "sha512-t7zK1Cheh0xvzfZbimztiE0wGnpV+YRsBg3tefcEBN3O4GzgLu6fFpA5HxEyVm3hHZW1jAC4OhoGEp7C5Ii6Eg==",
"cpu": [ "cpu": [
"ppc64" "ppc64"
], ],
@ -252,9 +252,9 @@
} }
}, },
"node_modules/@esbuild/linux-riscv64": { "node_modules/@esbuild/linux-riscv64": {
"version": "0.18.2", "version": "0.18.3",
"resolved": "https://registry.npmjs.org/@esbuild/linux-riscv64/-/linux-riscv64-0.18.2.tgz", "resolved": "https://registry.npmjs.org/@esbuild/linux-riscv64/-/linux-riscv64-0.18.3.tgz",
"integrity": "sha512-qW37zzKKN9C5l5LnVDriOK0eZRzQeixhtrfd5C78PAsTE15GeHU9G0oyT/u/IkNjEBjXWpTZOOHKNbjhrvuL9g==", "integrity": "sha512-fUZPtyCYih6y4lDYdSM4Yoax4nS7aH0/XixJStys+9tfp5cAlIAZhEVKOOdeGXmQn0IEyiUtlIsPnfObbeDQfQ==",
"cpu": [ "cpu": [
"riscv64" "riscv64"
], ],
@ -267,9 +267,9 @@
} }
}, },
"node_modules/@esbuild/linux-s390x": { "node_modules/@esbuild/linux-s390x": {
"version": "0.18.2", "version": "0.18.3",
"resolved": "https://registry.npmjs.org/@esbuild/linux-s390x/-/linux-s390x-0.18.2.tgz", "resolved": "https://registry.npmjs.org/@esbuild/linux-s390x/-/linux-s390x-0.18.3.tgz",
"integrity": "sha512-izzEFMRO8LaQIlX22+fTgP5I7Os3T51mtAWsRNpZ5pMfQIa9PqtgFAoRcb10DV+/YkH/TMMxQIlevUvDS6E4vw==", "integrity": "sha512-oIcK2LqHWqfMERqjvaKJ3QJmycHn723HsXIv5gH4iGfmePfSj+gi0ZQv2h4bHUg2bs2gJtV0DlIjGhEuvdgxLw==",
"cpu": [ "cpu": [
"s390x" "s390x"
], ],
@ -282,9 +282,9 @@
} }
}, },
"node_modules/@esbuild/linux-x64": { "node_modules/@esbuild/linux-x64": {
"version": "0.18.2", "version": "0.18.3",
"resolved": "https://registry.npmjs.org/@esbuild/linux-x64/-/linux-x64-0.18.2.tgz", "resolved": "https://registry.npmjs.org/@esbuild/linux-x64/-/linux-x64-0.18.3.tgz",
"integrity": "sha512-y5yqQ1ww4FfI9bQ1ZP/0k1rcgA6Ql2/AgzvqpowN0Q5tXDZkCavPdJbFXKrqA43vd1UTXt+AutTHYJ7km6e2Eg==", "integrity": "sha512-RW9lpfZ6XZ6f5to2DJPvt0f/4RXEW229Xf++quVoW+YbnPrcapIJChtD/AmZ8cK3hglO/hXxJjs21pV0/l7L5w==",
"cpu": [ "cpu": [
"x64" "x64"
], ],
@ -297,9 +297,9 @@
} }
}, },
"node_modules/@esbuild/netbsd-x64": { "node_modules/@esbuild/netbsd-x64": {
"version": "0.18.2", "version": "0.18.3",
"resolved": "https://registry.npmjs.org/@esbuild/netbsd-x64/-/netbsd-x64-0.18.2.tgz", "resolved": "https://registry.npmjs.org/@esbuild/netbsd-x64/-/netbsd-x64-0.18.3.tgz",
"integrity": "sha512-usNjpKFf83X4o60gdMD47NCblaSZ6DARf31/FyCzxOgnF80mJ+RhDs9RTqgyfH8KyduO5mjgInw9+ct286ayYA==", "integrity": "sha512-piZ2oBoaq58pKZvhgdV6PemlL30Uhd9GmmOkIGZYgChwNcyVSSl6iMEJxMzU7x44Lk9q+hJ6a343M/iVEMEvxA==",
"cpu": [ "cpu": [
"x64" "x64"
], ],
@ -312,9 +312,9 @@
} }
}, },
"node_modules/@esbuild/openbsd-x64": { "node_modules/@esbuild/openbsd-x64": {
"version": "0.18.2", "version": "0.18.3",
"resolved": "https://registry.npmjs.org/@esbuild/openbsd-x64/-/openbsd-x64-0.18.2.tgz", "resolved": "https://registry.npmjs.org/@esbuild/openbsd-x64/-/openbsd-x64-0.18.3.tgz",
"integrity": "sha512-6urzy1+VwcPuhG+5jwHA8lD9E87E5+ey3qKw2EhRS+qUmMxLvfwP8szWC2JHVGZDPEDge6fgn0pBj+y9rxDLwQ==", "integrity": "sha512-vaMfouYTz/4tKdQsXDccqhV6wgPEr+hfuxdNU5Pl/vQxYTsqcXv5DYEa5Z1RAxCoua5aEB+Uj5V7VT/bM92wxw==",
"cpu": [ "cpu": [
"x64" "x64"
], ],
@ -327,9 +327,9 @@
} }
}, },
"node_modules/@esbuild/sunos-x64": { "node_modules/@esbuild/sunos-x64": {
"version": "0.18.2", "version": "0.18.3",
"resolved": "https://registry.npmjs.org/@esbuild/sunos-x64/-/sunos-x64-0.18.2.tgz", "resolved": "https://registry.npmjs.org/@esbuild/sunos-x64/-/sunos-x64-0.18.3.tgz",
"integrity": "sha512-SMZPTACsvpKYAIl9o8nhnmMn6/lp62iMeV/2EBMtj+sW6dXwW9b0cLjihkBv4PG1CCRlwWKPZo43imqZxC95ZA==", "integrity": "sha512-Fa3rNQQ9q1qwy9u2cdDvuGKy3jmPnPPMDdyy/qbn5d395Pb9hjLYiPzX9BozXMPJDlCNofSY7jN3miM9gyAdHA==",
"cpu": [ "cpu": [
"x64" "x64"
], ],
@ -342,9 +342,9 @@
} }
}, },
"node_modules/@esbuild/win32-arm64": { "node_modules/@esbuild/win32-arm64": {
"version": "0.18.2", "version": "0.18.3",
"resolved": "https://registry.npmjs.org/@esbuild/win32-arm64/-/win32-arm64-0.18.2.tgz", "resolved": "https://registry.npmjs.org/@esbuild/win32-arm64/-/win32-arm64-0.18.3.tgz",
"integrity": "sha512-H2zzjPdzSDNwUnZdZf9/xfm0CYqHFXuenCMAx+tRzIRqWUT6MmZ9/q7722KnAZ6uPpq0RLs7EjCIIfmt6CaRGg==", "integrity": "sha512-LPJC8ub+9uzyC6ygVmp00dAqet1q1DsZ/OldGIIBt+y+Ctd1OfnKNlzQgXK8nxwY1G8fAhklFSeSRRgAUJnR0w==",
"cpu": [ "cpu": [
"arm64" "arm64"
], ],
@ -357,9 +357,9 @@
} }
}, },
"node_modules/@esbuild/win32-ia32": { "node_modules/@esbuild/win32-ia32": {
"version": "0.18.2", "version": "0.18.3",
"resolved": "https://registry.npmjs.org/@esbuild/win32-ia32/-/win32-ia32-0.18.2.tgz", "resolved": "https://registry.npmjs.org/@esbuild/win32-ia32/-/win32-ia32-0.18.3.tgz",
"integrity": "sha512-lfyjTN+FrKgvNvrH7nOLtaz58J/8coZOo4LQwgBMP4D7ZOurhvluXS3GjePLzq9GbWnJDZdKCKbMKhZPPcdJJA==", "integrity": "sha512-WtUyRspyxZR6NTc2HG4xd9Wvz8lP4C6OUY1gAqisrf151HvXIxsK0mfAacFJNS7EN2wvPTgjP+SM8vgBOx5+zA==",
"cpu": [ "cpu": [
"ia32" "ia32"
], ],
@ -372,9 +372,9 @@
} }
}, },
"node_modules/@esbuild/win32-x64": { "node_modules/@esbuild/win32-x64": {
"version": "0.18.2", "version": "0.18.3",
"resolved": "https://registry.npmjs.org/@esbuild/win32-x64/-/win32-x64-0.18.2.tgz", "resolved": "https://registry.npmjs.org/@esbuild/win32-x64/-/win32-x64-0.18.3.tgz",
"integrity": "sha512-Q4nIjqWXjxkELwd7kVepsJxbQ/6ERNsHpjz1j+IKjwSYw+g06U0RQOy5xh848AHvgr9itnGLa3cT2G5t0dBFsw==", "integrity": "sha512-Z8qCK4BkBm40j5KUM4NrkxYQS0R12cBO1NBVtI4vws6uwh1n/VaNu31Hm+n2cJUWdFbfH57PBghkhm9yLgmPfw==",
"cpu": [ "cpu": [
"x64" "x64"
], ],
@ -1647,9 +1647,9 @@
} }
}, },
"node_modules/esbuild": { "node_modules/esbuild": {
"version": "0.18.2", "version": "0.18.3",
"resolved": "https://registry.npmjs.org/esbuild/-/esbuild-0.18.2.tgz", "resolved": "https://registry.npmjs.org/esbuild/-/esbuild-0.18.3.tgz",
"integrity": "sha512-1P4sK9gXVcjvrrUjE94Hbo9goU+T6U1sdzLf+JJ+3uI6GEb4e4n3Wrqto9hZHUWabblpT2ifmC61LhZnLyTNFw==", "integrity": "sha512-eadWJC4CRpj93+miO5ZBlvCv+m2x6pzyNBznTvUeLFObMmxs1IMd8cCf6qiDVEZuDL6W8W7u+ZNW3GKEfOdDsA==",
"hasInstallScript": true, "hasInstallScript": true,
"bin": { "bin": {
"esbuild": "bin/esbuild" "esbuild": "bin/esbuild"
@ -1658,28 +1658,28 @@
"node": ">=12" "node": ">=12"
}, },
"optionalDependencies": { "optionalDependencies": {
"@esbuild/android-arm": "0.18.2", "@esbuild/android-arm": "0.18.3",
"@esbuild/android-arm64": "0.18.2", "@esbuild/android-arm64": "0.18.3",
"@esbuild/android-x64": "0.18.2", "@esbuild/android-x64": "0.18.3",
"@esbuild/darwin-arm64": "0.18.2", "@esbuild/darwin-arm64": "0.18.3",
"@esbuild/darwin-x64": "0.18.2", "@esbuild/darwin-x64": "0.18.3",
"@esbuild/freebsd-arm64": "0.18.2", "@esbuild/freebsd-arm64": "0.18.3",
"@esbuild/freebsd-x64": "0.18.2", "@esbuild/freebsd-x64": "0.18.3",
"@esbuild/linux-arm": "0.18.2", "@esbuild/linux-arm": "0.18.3",
"@esbuild/linux-arm64": "0.18.2", "@esbuild/linux-arm64": "0.18.3",
"@esbuild/linux-ia32": "0.18.2", "@esbuild/linux-ia32": "0.18.3",
"@esbuild/linux-loong64": "0.18.2", "@esbuild/linux-loong64": "0.18.3",
"@esbuild/linux-mips64el": "0.18.2", "@esbuild/linux-mips64el": "0.18.3",
"@esbuild/linux-ppc64": "0.18.2", "@esbuild/linux-ppc64": "0.18.3",
"@esbuild/linux-riscv64": "0.18.2", "@esbuild/linux-riscv64": "0.18.3",
"@esbuild/linux-s390x": "0.18.2", "@esbuild/linux-s390x": "0.18.3",
"@esbuild/linux-x64": "0.18.2", "@esbuild/linux-x64": "0.18.3",
"@esbuild/netbsd-x64": "0.18.2", "@esbuild/netbsd-x64": "0.18.3",
"@esbuild/openbsd-x64": "0.18.2", "@esbuild/openbsd-x64": "0.18.3",
"@esbuild/sunos-x64": "0.18.2", "@esbuild/sunos-x64": "0.18.3",
"@esbuild/win32-arm64": "0.18.2", "@esbuild/win32-arm64": "0.18.3",
"@esbuild/win32-ia32": "0.18.2", "@esbuild/win32-ia32": "0.18.3",
"@esbuild/win32-x64": "0.18.2" "@esbuild/win32-x64": "0.18.3"
} }
}, },
"node_modules/escalade": { "node_modules/escalade": {
@ -6797,135 +6797,135 @@
} }
}, },
"@esbuild/android-arm": { "@esbuild/android-arm": {
"version": "0.18.2", "version": "0.18.3",
"resolved": "https://registry.npmjs.org/@esbuild/android-arm/-/android-arm-0.18.2.tgz", "resolved": "https://registry.npmjs.org/@esbuild/android-arm/-/android-arm-0.18.3.tgz",
"integrity": "sha512-YAnQBHlY0IvYtvY0avnXjI8ywW23emEjk5XExqbFmypath+Snq9MgY1IS47rnqBKVSqnl0ElDt221ZgaeRrkXg==", "integrity": "sha512-QOn3VIlL6Qv1eHBpQB/s7simaZgGss2ASyxDOwYSLmc6vD0uuizZkuYawHmuLjWEm5wPwp0JQWhbpaYwwGevYw==",
"optional": true "optional": true
}, },
"@esbuild/android-arm64": { "@esbuild/android-arm64": {
"version": "0.18.2", "version": "0.18.3",
"resolved": "https://registry.npmjs.org/@esbuild/android-arm64/-/android-arm64-0.18.2.tgz", "resolved": "https://registry.npmjs.org/@esbuild/android-arm64/-/android-arm64-0.18.3.tgz",
"integrity": "sha512-1Y2pb0hLdmji8I0zBwNsYSDN7zJSQqufgLOuOsrrod00WEAgKywQR5MB/E046Is/YTP4bgcPS4BioaSDBaLaTg==", "integrity": "sha512-PgabCsoaEEnnOiF6rUhOBXgYoLFIrHWP6mfLOzuQ1oZ1lwBdTL0hp5ivC4K3Kvz3BD8EipjeQo6l0aty3nr4qQ==",
"optional": true "optional": true
}, },
"@esbuild/android-x64": { "@esbuild/android-x64": {
"version": "0.18.2", "version": "0.18.3",
"resolved": "https://registry.npmjs.org/@esbuild/android-x64/-/android-x64-0.18.2.tgz", "resolved": "https://registry.npmjs.org/@esbuild/android-x64/-/android-x64-0.18.3.tgz",
"integrity": "sha512-P047Mh3pj8uYVE3A/B3QDX6nG8dKbHLJ+48R6Y0CRXCJ5PkXJxdHOTaS8SYs6eSR3FFU6/YQ5TishQXVHX7F5A==", "integrity": "sha512-1OkJf8wNX1W5ucbp5HrK+z42b9DINb4ix59oJH/PIsh9cyFMqjgRKtCBXg0zEWhkmP1k3egdfrnS7cDTpLH43g==",
"optional": true "optional": true
}, },
"@esbuild/darwin-arm64": { "@esbuild/darwin-arm64": {
"version": "0.18.2", "version": "0.18.3",
"resolved": "https://registry.npmjs.org/@esbuild/darwin-arm64/-/darwin-arm64-0.18.2.tgz", "resolved": "https://registry.npmjs.org/@esbuild/darwin-arm64/-/darwin-arm64-0.18.3.tgz",
"integrity": "sha512-a3Rkqd0tGVYMEKNy9SstWEdeBmM60l8FVD5o4rmwHr3xO1LbLqtCJSrWGbnf37hevo6m437mURVmpEHOmkXeTA==", "integrity": "sha512-57aofORpY7wDAuMs6DeqpmgSnVfZ63RgGbR/BHdOSTqJgYvHDCMY7/o1myFntl3k0YxtLE3WAm56nMf4qy3UDw==",
"optional": true "optional": true
}, },
"@esbuild/darwin-x64": { "@esbuild/darwin-x64": {
"version": "0.18.2", "version": "0.18.3",
"resolved": "https://registry.npmjs.org/@esbuild/darwin-x64/-/darwin-x64-0.18.2.tgz", "resolved": "https://registry.npmjs.org/@esbuild/darwin-x64/-/darwin-x64-0.18.3.tgz",
"integrity": "sha512-cvH58adz9L10JNsIcgtkWNS/1eutjRTi3rtWz1s3ZhR64BpdmkxJBAXE/UjqybyNAWLhaN8mPJdlYI2f+tQA7g==", "integrity": "sha512-NVBqMnxT9qvgu7Z322LUDlwjh4GDk6wEePyAQnHF9noxik/WvLFmr5v3Vgz5LSvqFducLCxsdmLztKhdpFW0Gg==",
"optional": true "optional": true
}, },
"@esbuild/freebsd-arm64": { "@esbuild/freebsd-arm64": {
"version": "0.18.2", "version": "0.18.3",
"resolved": "https://registry.npmjs.org/@esbuild/freebsd-arm64/-/freebsd-arm64-0.18.2.tgz", "resolved": "https://registry.npmjs.org/@esbuild/freebsd-arm64/-/freebsd-arm64-0.18.3.tgz",
"integrity": "sha512-68rGMGUdgmq+c5IvseCMqY4yaa2CAY/DIILMBA6bEU1caISF7fXnV69B1uU4s3ERuVDcasVVwiAFyNxCtkS6Zg==", "integrity": "sha512-XiLK1AsCk2wKxN7j8h9GXXCs8FPZhp07U0rnpwRkAVSVGgLaIWYSqpTRzKjAfqJiZlp+XKo1HwsmDdICEKB3Dg==",
"optional": true "optional": true
}, },
"@esbuild/freebsd-x64": { "@esbuild/freebsd-x64": {
"version": "0.18.2", "version": "0.18.3",
"resolved": "https://registry.npmjs.org/@esbuild/freebsd-x64/-/freebsd-x64-0.18.2.tgz", "resolved": "https://registry.npmjs.org/@esbuild/freebsd-x64/-/freebsd-x64-0.18.3.tgz",
"integrity": "sha512-ZSR9On/rXoYuAtrXo5hYKy7OuZwKZyFh2rr6L3TX4UeR1tWLf84aLyAFt7e0tlRbh4zNgqFx+ePWmsSHw7L9Bw==", "integrity": "sha512-xyITfrF0G3l1gwR79hvNCCWKQ/16uK14xNNPFgzjbIqF4EpBvhO6l3jrWxXFUW51z6dVIl2Szh3x3uIbBWzH1Q==",
"optional": true "optional": true
}, },
"@esbuild/linux-arm": { "@esbuild/linux-arm": {
"version": "0.18.2", "version": "0.18.3",
"resolved": "https://registry.npmjs.org/@esbuild/linux-arm/-/linux-arm-0.18.2.tgz", "resolved": "https://registry.npmjs.org/@esbuild/linux-arm/-/linux-arm-0.18.3.tgz",
"integrity": "sha512-jAbA75qJ70T5AOdmw9X8675ppeRfj7j57sOypoZ4mQlfQ/LKF8eoeLzTYVo8+aqLKqeIIl0vQ4hKOB0FyG98Zg==", "integrity": "sha512-fc/T0QHMzvmnlF+kfD6bHLB8u+17gg13260p/E86yYjVoKNFjonL/+Y0GGQjMbFUas9QijqOa7pcR00a9RNkwg==",
"optional": true "optional": true
}, },
"@esbuild/linux-arm64": { "@esbuild/linux-arm64": {
"version": "0.18.2", "version": "0.18.3",
"resolved": "https://registry.npmjs.org/@esbuild/linux-arm64/-/linux-arm64-0.18.2.tgz", "resolved": "https://registry.npmjs.org/@esbuild/linux-arm64/-/linux-arm64-0.18.3.tgz",
"integrity": "sha512-DFKavAzbu/n9HXWuetxmYN10XnfzW7FgOgpcrGD8eXaiu77KdgB+OVWA83x9FtDYtsoFpfdlDuVFAQFfrhu77A==", "integrity": "sha512-lsKUYVd8L/j2uNs8dhMjMsKC5MHYh77gR9EThu7YCeeFz1XpIkx1I4a7mhoVfPS2VPVD1pMCh+PgxuAHUcEmXw==",
"optional": true "optional": true
}, },
"@esbuild/linux-ia32": { "@esbuild/linux-ia32": {
"version": "0.18.2", "version": "0.18.3",
"resolved": "https://registry.npmjs.org/@esbuild/linux-ia32/-/linux-ia32-0.18.2.tgz", "resolved": "https://registry.npmjs.org/@esbuild/linux-ia32/-/linux-ia32-0.18.3.tgz",
"integrity": "sha512-VEaK3Z+vJyDwwPsP0sovaEw1foDzrMs7XQNYEIFkOwMjSe2BipKRKUUyrznil0p8qqsK7U8W+T7oNqZpgdnD2Q==", "integrity": "sha512-EyfGWeOwRqK5Xj18vok0qv8IFBZ1/+hKV+cqD44oVhGsxHo9TmPtoSiDrWn8Sa2swq/VuO5Aiog6YPDj81oIkA==",
"optional": true "optional": true
}, },
"@esbuild/linux-loong64": { "@esbuild/linux-loong64": {
"version": "0.18.2", "version": "0.18.3",
"resolved": "https://registry.npmjs.org/@esbuild/linux-loong64/-/linux-loong64-0.18.2.tgz", "resolved": "https://registry.npmjs.org/@esbuild/linux-loong64/-/linux-loong64-0.18.3.tgz",
"integrity": "sha512-Af1uZdB0oeJo4PW67l9aw94oakSamFxhC6ltC2eDkndozd9QygVNMTF7s7uxTLjo+BJqyVqG9wjmLCYF1o4NmA==", "integrity": "sha512-PwXkcl3t0kSeYH5RuJIeh/fHOzKZd+ZdifAWzpVO+9TLWArutTFBJvOSkTZ3CcqQqNrTj1Qyo6nqE8MQj/a7cQ==",
"optional": true "optional": true
}, },
"@esbuild/linux-mips64el": { "@esbuild/linux-mips64el": {
"version": "0.18.2", "version": "0.18.3",
"resolved": "https://registry.npmjs.org/@esbuild/linux-mips64el/-/linux-mips64el-0.18.2.tgz", "resolved": "https://registry.npmjs.org/@esbuild/linux-mips64el/-/linux-mips64el-0.18.3.tgz",
"integrity": "sha512-WcTbt61+9dREuOFKXac4Qg+3OuRhLxPL9lmkI2P7fGuq/fWS2qq+AvGGVLMyk+OtXGDjyQolcEDeYlRoOmjRYQ==", "integrity": "sha512-CRVkkSXf5GQcq7Am2a2tdIn85oqi/bkjuPvhNqcdeTgI0xgNbqLnEPRy2AEGkRuaJWB5uCX1IC4sqnY8ET14Yg==",
"optional": true "optional": true
}, },
"@esbuild/linux-ppc64": { "@esbuild/linux-ppc64": {
"version": "0.18.2", "version": "0.18.3",
"resolved": "https://registry.npmjs.org/@esbuild/linux-ppc64/-/linux-ppc64-0.18.2.tgz", "resolved": "https://registry.npmjs.org/@esbuild/linux-ppc64/-/linux-ppc64-0.18.3.tgz",
"integrity": "sha512-Ov+VHayvCPb52axma6+xm8QDawRjwHscPXedHg4U92DxlhKQ0H+6onRiC3J9kKI50p8pKKypprpCWrRrXjZN7Q==", "integrity": "sha512-t7zK1Cheh0xvzfZbimztiE0wGnpV+YRsBg3tefcEBN3O4GzgLu6fFpA5HxEyVm3hHZW1jAC4OhoGEp7C5Ii6Eg==",
"optional": true "optional": true
}, },
"@esbuild/linux-riscv64": { "@esbuild/linux-riscv64": {
"version": "0.18.2", "version": "0.18.3",
"resolved": "https://registry.npmjs.org/@esbuild/linux-riscv64/-/linux-riscv64-0.18.2.tgz", "resolved": "https://registry.npmjs.org/@esbuild/linux-riscv64/-/linux-riscv64-0.18.3.tgz",
"integrity": "sha512-qW37zzKKN9C5l5LnVDriOK0eZRzQeixhtrfd5C78PAsTE15GeHU9G0oyT/u/IkNjEBjXWpTZOOHKNbjhrvuL9g==", "integrity": "sha512-fUZPtyCYih6y4lDYdSM4Yoax4nS7aH0/XixJStys+9tfp5cAlIAZhEVKOOdeGXmQn0IEyiUtlIsPnfObbeDQfQ==",
"optional": true "optional": true
}, },
"@esbuild/linux-s390x": { "@esbuild/linux-s390x": {
"version": "0.18.2", "version": "0.18.3",
"resolved": "https://registry.npmjs.org/@esbuild/linux-s390x/-/linux-s390x-0.18.2.tgz", "resolved": "https://registry.npmjs.org/@esbuild/linux-s390x/-/linux-s390x-0.18.3.tgz",
"integrity": "sha512-izzEFMRO8LaQIlX22+fTgP5I7Os3T51mtAWsRNpZ5pMfQIa9PqtgFAoRcb10DV+/YkH/TMMxQIlevUvDS6E4vw==", "integrity": "sha512-oIcK2LqHWqfMERqjvaKJ3QJmycHn723HsXIv5gH4iGfmePfSj+gi0ZQv2h4bHUg2bs2gJtV0DlIjGhEuvdgxLw==",
"optional": true "optional": true
}, },
"@esbuild/linux-x64": { "@esbuild/linux-x64": {
"version": "0.18.2", "version": "0.18.3",
"resolved": "https://registry.npmjs.org/@esbuild/linux-x64/-/linux-x64-0.18.2.tgz", "resolved": "https://registry.npmjs.org/@esbuild/linux-x64/-/linux-x64-0.18.3.tgz",
"integrity": "sha512-y5yqQ1ww4FfI9bQ1ZP/0k1rcgA6Ql2/AgzvqpowN0Q5tXDZkCavPdJbFXKrqA43vd1UTXt+AutTHYJ7km6e2Eg==", "integrity": "sha512-RW9lpfZ6XZ6f5to2DJPvt0f/4RXEW229Xf++quVoW+YbnPrcapIJChtD/AmZ8cK3hglO/hXxJjs21pV0/l7L5w==",
"optional": true "optional": true
}, },
"@esbuild/netbsd-x64": { "@esbuild/netbsd-x64": {
"version": "0.18.2", "version": "0.18.3",
"resolved": "https://registry.npmjs.org/@esbuild/netbsd-x64/-/netbsd-x64-0.18.2.tgz", "resolved": "https://registry.npmjs.org/@esbuild/netbsd-x64/-/netbsd-x64-0.18.3.tgz",
"integrity": "sha512-usNjpKFf83X4o60gdMD47NCblaSZ6DARf31/FyCzxOgnF80mJ+RhDs9RTqgyfH8KyduO5mjgInw9+ct286ayYA==", "integrity": "sha512-piZ2oBoaq58pKZvhgdV6PemlL30Uhd9GmmOkIGZYgChwNcyVSSl6iMEJxMzU7x44Lk9q+hJ6a343M/iVEMEvxA==",
"optional": true "optional": true
}, },
"@esbuild/openbsd-x64": { "@esbuild/openbsd-x64": {
"version": "0.18.2", "version": "0.18.3",
"resolved": "https://registry.npmjs.org/@esbuild/openbsd-x64/-/openbsd-x64-0.18.2.tgz", "resolved": "https://registry.npmjs.org/@esbuild/openbsd-x64/-/openbsd-x64-0.18.3.tgz",
"integrity": "sha512-6urzy1+VwcPuhG+5jwHA8lD9E87E5+ey3qKw2EhRS+qUmMxLvfwP8szWC2JHVGZDPEDge6fgn0pBj+y9rxDLwQ==", "integrity": "sha512-vaMfouYTz/4tKdQsXDccqhV6wgPEr+hfuxdNU5Pl/vQxYTsqcXv5DYEa5Z1RAxCoua5aEB+Uj5V7VT/bM92wxw==",
"optional": true "optional": true
}, },
"@esbuild/sunos-x64": { "@esbuild/sunos-x64": {
"version": "0.18.2", "version": "0.18.3",
"resolved": "https://registry.npmjs.org/@esbuild/sunos-x64/-/sunos-x64-0.18.2.tgz", "resolved": "https://registry.npmjs.org/@esbuild/sunos-x64/-/sunos-x64-0.18.3.tgz",
"integrity": "sha512-SMZPTACsvpKYAIl9o8nhnmMn6/lp62iMeV/2EBMtj+sW6dXwW9b0cLjihkBv4PG1CCRlwWKPZo43imqZxC95ZA==", "integrity": "sha512-Fa3rNQQ9q1qwy9u2cdDvuGKy3jmPnPPMDdyy/qbn5d395Pb9hjLYiPzX9BozXMPJDlCNofSY7jN3miM9gyAdHA==",
"optional": true "optional": true
}, },
"@esbuild/win32-arm64": { "@esbuild/win32-arm64": {
"version": "0.18.2", "version": "0.18.3",
"resolved": "https://registry.npmjs.org/@esbuild/win32-arm64/-/win32-arm64-0.18.2.tgz", "resolved": "https://registry.npmjs.org/@esbuild/win32-arm64/-/win32-arm64-0.18.3.tgz",
"integrity": "sha512-H2zzjPdzSDNwUnZdZf9/xfm0CYqHFXuenCMAx+tRzIRqWUT6MmZ9/q7722KnAZ6uPpq0RLs7EjCIIfmt6CaRGg==", "integrity": "sha512-LPJC8ub+9uzyC6ygVmp00dAqet1q1DsZ/OldGIIBt+y+Ctd1OfnKNlzQgXK8nxwY1G8fAhklFSeSRRgAUJnR0w==",
"optional": true "optional": true
}, },
"@esbuild/win32-ia32": { "@esbuild/win32-ia32": {
"version": "0.18.2", "version": "0.18.3",
"resolved": "https://registry.npmjs.org/@esbuild/win32-ia32/-/win32-ia32-0.18.2.tgz", "resolved": "https://registry.npmjs.org/@esbuild/win32-ia32/-/win32-ia32-0.18.3.tgz",
"integrity": "sha512-lfyjTN+FrKgvNvrH7nOLtaz58J/8coZOo4LQwgBMP4D7ZOurhvluXS3GjePLzq9GbWnJDZdKCKbMKhZPPcdJJA==", "integrity": "sha512-WtUyRspyxZR6NTc2HG4xd9Wvz8lP4C6OUY1gAqisrf151HvXIxsK0mfAacFJNS7EN2wvPTgjP+SM8vgBOx5+zA==",
"optional": true "optional": true
}, },
"@esbuild/win32-x64": { "@esbuild/win32-x64": {
"version": "0.18.2", "version": "0.18.3",
"resolved": "https://registry.npmjs.org/@esbuild/win32-x64/-/win32-x64-0.18.2.tgz", "resolved": "https://registry.npmjs.org/@esbuild/win32-x64/-/win32-x64-0.18.3.tgz",
"integrity": "sha512-Q4nIjqWXjxkELwd7kVepsJxbQ/6ERNsHpjz1j+IKjwSYw+g06U0RQOy5xh848AHvgr9itnGLa3cT2G5t0dBFsw==", "integrity": "sha512-Z8qCK4BkBm40j5KUM4NrkxYQS0R12cBO1NBVtI4vws6uwh1n/VaNu31Hm+n2cJUWdFbfH57PBghkhm9yLgmPfw==",
"optional": true "optional": true
}, },
"@jridgewell/gen-mapping": { "@jridgewell/gen-mapping": {
@ -7896,32 +7896,32 @@
"integrity": "sha512-V0hjH4dGPh9Ao5p0MoRY6BVqtwCjhz6vI5LT8AJ55H+4g9/4vbHx1I54fS0XuclLhDHArPQCiMjDxjaL8fPxhw==" "integrity": "sha512-V0hjH4dGPh9Ao5p0MoRY6BVqtwCjhz6vI5LT8AJ55H+4g9/4vbHx1I54fS0XuclLhDHArPQCiMjDxjaL8fPxhw=="
}, },
"esbuild": { "esbuild": {
"version": "0.18.2", "version": "0.18.3",
"resolved": "https://registry.npmjs.org/esbuild/-/esbuild-0.18.2.tgz", "resolved": "https://registry.npmjs.org/esbuild/-/esbuild-0.18.3.tgz",
"integrity": "sha512-1P4sK9gXVcjvrrUjE94Hbo9goU+T6U1sdzLf+JJ+3uI6GEb4e4n3Wrqto9hZHUWabblpT2ifmC61LhZnLyTNFw==", "integrity": "sha512-eadWJC4CRpj93+miO5ZBlvCv+m2x6pzyNBznTvUeLFObMmxs1IMd8cCf6qiDVEZuDL6W8W7u+ZNW3GKEfOdDsA==",
"requires": { "requires": {
"@esbuild/android-arm": "0.18.2", "@esbuild/android-arm": "0.18.3",
"@esbuild/android-arm64": "0.18.2", "@esbuild/android-arm64": "0.18.3",
"@esbuild/android-x64": "0.18.2", "@esbuild/android-x64": "0.18.3",
"@esbuild/darwin-arm64": "0.18.2", "@esbuild/darwin-arm64": "0.18.3",
"@esbuild/darwin-x64": "0.18.2", "@esbuild/darwin-x64": "0.18.3",
"@esbuild/freebsd-arm64": "0.18.2", "@esbuild/freebsd-arm64": "0.18.3",
"@esbuild/freebsd-x64": "0.18.2", "@esbuild/freebsd-x64": "0.18.3",
"@esbuild/linux-arm": "0.18.2", "@esbuild/linux-arm": "0.18.3",
"@esbuild/linux-arm64": "0.18.2", "@esbuild/linux-arm64": "0.18.3",
"@esbuild/linux-ia32": "0.18.2", "@esbuild/linux-ia32": "0.18.3",
"@esbuild/linux-loong64": "0.18.2", "@esbuild/linux-loong64": "0.18.3",
"@esbuild/linux-mips64el": "0.18.2", "@esbuild/linux-mips64el": "0.18.3",
"@esbuild/linux-ppc64": "0.18.2", "@esbuild/linux-ppc64": "0.18.3",
"@esbuild/linux-riscv64": "0.18.2", "@esbuild/linux-riscv64": "0.18.3",
"@esbuild/linux-s390x": "0.18.2", "@esbuild/linux-s390x": "0.18.3",
"@esbuild/linux-x64": "0.18.2", "@esbuild/linux-x64": "0.18.3",
"@esbuild/netbsd-x64": "0.18.2", "@esbuild/netbsd-x64": "0.18.3",
"@esbuild/openbsd-x64": "0.18.2", "@esbuild/openbsd-x64": "0.18.3",
"@esbuild/sunos-x64": "0.18.2", "@esbuild/sunos-x64": "0.18.3",
"@esbuild/win32-arm64": "0.18.2", "@esbuild/win32-arm64": "0.18.3",
"@esbuild/win32-ia32": "0.18.2", "@esbuild/win32-ia32": "0.18.3",
"@esbuild/win32-x64": "0.18.2" "@esbuild/win32-x64": "0.18.3"
} }
}, },
"escalade": { "escalade": {

@ -23,7 +23,7 @@
"any-date-parser": "^1.5.4", "any-date-parser": "^1.5.4",
"browserslist": "^4.21.7", "browserslist": "^4.21.7",
"cheerio": "^1.0.0-rc.12", "cheerio": "^1.0.0-rc.12",
"esbuild": "^0.18.2", "esbuild": "^0.18.3",
"fs-cheerio": "^3.0.0", "fs-cheerio": "^3.0.0",
"inline-source": "^8.0.2", "inline-source": "^8.0.2",
"jsdom": "^22.1.0", "jsdom": "^22.1.0",

@ -32,6 +32,8 @@ interface formWindow extends Window {
userExpiryMessage: string; userExpiryMessage: string;
emailRequired: boolean; emailRequired: boolean;
captcha: boolean; captcha: boolean;
reCAPTCHA: boolean;
reCAPTCHASiteKey: string;
} }
loadLangSelector("form"); loadLangSelector("form");
@ -263,7 +265,7 @@ let prevCaptcha = "";
function baseValidator(oncomplete: (valid: boolean) => void): void { function baseValidator(oncomplete: (valid: boolean) => void): void {
let captchaChecked = false; let captchaChecked = false;
let captchaChange = false; let captchaChange = false;
if (window.captcha) { if (window.captcha && !window.reCAPTCHA) {
captchaChange = captchaInput.value != prevCaptcha; captchaChange = captchaInput.value != prevCaptcha;
if (captchaChange) { if (captchaChange) {
prevCaptcha = captchaInput.value; prevCaptcha = captchaInput.value;
@ -305,7 +307,7 @@ function baseValidator(oncomplete: (valid: boolean) => void): void {
oncomplete(false); oncomplete(false);
return; return;
} }
if (window.captcha) { if (window.captcha && !window.reCAPTCHA) {
if (!captchaChange) { if (!captchaChange) {
oncomplete(captchaVerified); oncomplete(captchaVerified);
return; return;
@ -319,6 +321,21 @@ function baseValidator(oncomplete: (valid: boolean) => void): void {
} }
} }
interface GreCAPTCHA {
render: (container: HTMLDivElement, parameters: {
sitekey?: string,
theme?: string,
size?: string,
tabindex?: number,
"callback"?: () => void,
"expired-callback"?: () => void,
"error-callback"?: () => void
}) => void;
getResponse: (opt_widget_id?: HTMLDivElement) => string;
}
declare var grecaptcha: GreCAPTCHA
let r = initValidator(passwordField, rePasswordField, submitButton, submitSpan, baseValidator); let r = initValidator(passwordField, rePasswordField, submitButton, submitSpan, baseValidator);
var requirements = r[0]; var requirements = r[0];
var validatorFunc = r[1] as () => void; var validatorFunc = r[1] as () => void;
@ -361,7 +378,7 @@ const genCaptcha = () => {
}); });
}; };
if (window.captcha) { if (window.captcha && !window.reCAPTCHA) {
genCaptcha(); genCaptcha();
(document.getElementById("captcha-regen") as HTMLSpanElement).onclick = genCaptcha; (document.getElementById("captcha-regen") as HTMLSpanElement).onclick = genCaptcha;
captchaInput.onkeyup = validatorFunc; captchaInput.onkeyup = validatorFunc;
@ -369,7 +386,7 @@ if (window.captcha) {
const create = (event: SubmitEvent) => { const create = (event: SubmitEvent) => {
event.preventDefault(); event.preventDefault();
if (window.captcha && !captchaVerified) { if (window.captcha && !window.reCAPTCHA && !captchaVerified) {
} }
toggleLoader(submitSpan); toggleLoader(submitSpan);
@ -401,9 +418,13 @@ const create = (event: SubmitEvent) => {
} }
} }
if (window.captcha) { if (window.captcha) {
if (window.reCAPTCHA) {
send.captcha_text = grecaptcha.getResponse();
} else {
send.captcha_id = captchaID; send.captcha_id = captchaID;
send.captcha_text = captchaInput.value; send.captcha_text = captchaInput.value;
} }
}
_post("/newUser", send, (req: XMLHttpRequest) => { _post("/newUser", send, (req: XMLHttpRequest) => {
if (req.readyState == 4) { if (req.readyState == 4) {
let vals = req.response as respDTO; let vals = req.response as respDTO;

@ -1,9 +1,12 @@
package main package main
import ( import (
"encoding/json"
"html/template" "html/template"
"io"
"io/fs" "io/fs"
"net/http" "net/http"
"net/url"
"strings" "strings"
"time" "time"
@ -323,6 +326,9 @@ func (app *appContext) GenCaptcha(gc *gin.Context) {
} }
func (app *appContext) verifyCaptcha(code, id, text string) bool { func (app *appContext) verifyCaptcha(code, id, text string) bool {
reCAPTCHA := app.config.Section("captcha").Key("recaptcha").MustBool(false)
if !reCAPTCHA {
// internal CAPTCHA
inv, ok := app.storage.invites[code] inv, ok := app.storage.invites[code]
if !ok || inv.Captchas == nil { if !ok || inv.Captchas == nil {
app.debug.Printf("Couldn't find invite \"%s\"", code) app.debug.Printf("Couldn't find invite \"%s\"", code)
@ -336,6 +342,49 @@ func (app *appContext) verifyCaptcha(code, id, text string) bool {
return strings.ToLower(c.Text) == strings.ToLower(text) return strings.ToLower(c.Text) == strings.ToLower(text)
} }
// reCAPTCHA
msg := ReCaptchaRequestDTO{
Secret: app.config.Section("captcha").Key("recaptcha_secret_key").MustString(""),
Response: text,
}
// Why doesn't this endpoint accept JSON???
urlencode := url.Values{}
urlencode.Set("secret", msg.Secret)
urlencode.Set("response", msg.Response)
req, _ := http.NewRequest("POST", "https://www.google.com/recaptcha/api/siteverify", strings.NewReader(urlencode.Encode()))
req.Header.Add("Content-Type", "application/x-www-form-urlencoded")
resp, err := http.DefaultClient.Do(req)
if err != nil || resp.StatusCode != 200 {
app.err.Printf("Failed to read reCAPTCHA status (%d): %+v\n", resp.Status, err)
return false
}
defer resp.Body.Close()
var data ReCaptchaResponseDTO
body, err := io.ReadAll(resp.Body)
err = json.Unmarshal(body, &data)
if err != nil {
app.err.Printf("Failed to unmarshal reCAPTCHA response: %+v\n", err)
return false
}
hostname := app.config.Section("captcha").Key("recaptcha_hostname").MustString("")
if strings.ToLower(data.Hostname) != strings.ToLower(hostname) && data.Hostname != "" {
app.debug.Printf("Invalidating reCAPTCHA request: Hostnames didn't match (Wanted \"%s\", got \"%s\"\n", hostname, data.Hostname)
return false
}
if len(data.ErrorCodes) > 0 {
app.err.Printf("reCAPTCHA returned errors: %+v\n", data.ErrorCodes)
return false
}
return data.Success
}
// @Summary returns 204 if the given Captcha contents is correct for the corresponding captcha ID and invite code. // @Summary returns 204 if the given Captcha contents is correct for the corresponding captcha ID and invite code.
// @Param code path string true "invite code" // @Param code path string true "invite code"
// @Param captchaID path string true "captcha ID" // @Param captchaID path string true "captcha ID"
@ -497,6 +546,8 @@ func (app *appContext) InviteProxy(gc *gin.Context) {
"matrixEnabled": matrix, "matrixEnabled": matrix,
"emailRequired": app.config.Section("email").Key("required").MustBool(false), "emailRequired": app.config.Section("email").Key("required").MustBool(false),
"captcha": app.config.Section("captcha").Key("enabled").MustBool(false), "captcha": app.config.Section("captcha").Key("enabled").MustBool(false),
"reCAPTCHA": app.config.Section("captcha").Key("recaptcha").MustBool(false),
"reCAPTCHASiteKey": app.config.Section("captcha").Key("recaptcha_site_key").MustString(""),
} }
if telegram { if telegram {
data["telegramPIN"] = app.telegram.NewAuthToken() data["telegramPIN"] = app.telegram.NewAuthToken()

Loading…
Cancel
Save