From 4014e9315548b55977155de857022246d59bc7b1 Mon Sep 17 00:00:00 2001 From: Harvey Tindall Date: Thu, 15 Jun 2023 17:11:27 +0100 Subject: [PATCH] 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. --- config/config-base.json | 35 ++++ html/form-base.html | 13 ++ html/form.html | 6 +- models.go | 14 ++ package-lock.json | 368 ++++++++++++++++++++-------------------- package.json | 2 +- ts/form.ts | 33 +++- views.go | 65 ++++++- 8 files changed, 336 insertions(+), 200 deletions(-) diff --git a/config/config-base.json b/config/config-base.json index 52b277a..f8ed5ee 100644 --- a/config/config-base.json +++ b/config/config-base.json @@ -335,6 +335,41 @@ "type": "bool", "value": false, "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." } } }, diff --git a/html/form-base.html b/html/form-base.html index 55229a6..9b9e667 100644 --- a/html/form-base.html +++ b/html/form-base.html @@ -27,10 +27,23 @@ window.matrixRequired = {{ .matrixRequired }}; window.matrixUserID = "{{ .matrixUser }}"; window.captcha = {{ .captcha }}; + window.reCAPTCHA = {{ .reCAPTCHA }}; + window.reCAPTCHASiteKey = "{{ .reCAPTCHASiteKey }}"; {{ if .passwordReset }} {{ else }} +{{ if .reCAPTCHA }} + + +{{ end }} {{ end }} {{ end }} diff --git a/html/form.html b/html/form.html index 635d5a5..c88721f 100644 --- a/html/form.html +++ b/html/form.html @@ -180,9 +180,11 @@ {{ if .captcha }}
- CAPTCHA -
+ CAPTCHA {{ if not .reCAPTCHA }}{{ end }} +
+ {{ if not .reCAPTCHA }} + {{ end }}
{{ end }} {{ if .contactMessage }} diff --git a/models.go b/models.go index db67cde..d553268 100644 --- a/models.go +++ b/models.go @@ -359,3 +359,17 @@ type genCaptchaDTO struct { type forUserDTO struct { 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"` +} diff --git a/package-lock.json b/package-lock.json index bca893c..173cc4f 100644 --- a/package-lock.json +++ b/package-lock.json @@ -15,7 +15,7 @@ "any-date-parser": "^1.5.4", "browserslist": "^4.21.7", "cheerio": "^1.0.0-rc.12", - "esbuild": "^0.18.2", + "esbuild": "^0.18.3", "fs-cheerio": "^3.0.0", "inline-source": "^8.0.2", "jsdom": "^22.1.0", @@ -57,9 +57,9 @@ } }, "node_modules/@esbuild/android-arm": { - "version": "0.18.2", - "resolved": "https://registry.npmjs.org/@esbuild/android-arm/-/android-arm-0.18.2.tgz", - "integrity": "sha512-YAnQBHlY0IvYtvY0avnXjI8ywW23emEjk5XExqbFmypath+Snq9MgY1IS47rnqBKVSqnl0ElDt221ZgaeRrkXg==", + "version": "0.18.3", + "resolved": "https://registry.npmjs.org/@esbuild/android-arm/-/android-arm-0.18.3.tgz", + "integrity": "sha512-QOn3VIlL6Qv1eHBpQB/s7simaZgGss2ASyxDOwYSLmc6vD0uuizZkuYawHmuLjWEm5wPwp0JQWhbpaYwwGevYw==", "cpu": [ "arm" ], @@ -72,9 +72,9 @@ } }, "node_modules/@esbuild/android-arm64": { - "version": "0.18.2", - "resolved": "https://registry.npmjs.org/@esbuild/android-arm64/-/android-arm64-0.18.2.tgz", - "integrity": "sha512-1Y2pb0hLdmji8I0zBwNsYSDN7zJSQqufgLOuOsrrod00WEAgKywQR5MB/E046Is/YTP4bgcPS4BioaSDBaLaTg==", + "version": "0.18.3", + "resolved": "https://registry.npmjs.org/@esbuild/android-arm64/-/android-arm64-0.18.3.tgz", + "integrity": "sha512-PgabCsoaEEnnOiF6rUhOBXgYoLFIrHWP6mfLOzuQ1oZ1lwBdTL0hp5ivC4K3Kvz3BD8EipjeQo6l0aty3nr4qQ==", "cpu": [ "arm64" ], @@ -87,9 +87,9 @@ } }, "node_modules/@esbuild/android-x64": { - "version": "0.18.2", - "resolved": "https://registry.npmjs.org/@esbuild/android-x64/-/android-x64-0.18.2.tgz", - "integrity": "sha512-P047Mh3pj8uYVE3A/B3QDX6nG8dKbHLJ+48R6Y0CRXCJ5PkXJxdHOTaS8SYs6eSR3FFU6/YQ5TishQXVHX7F5A==", + "version": "0.18.3", + "resolved": "https://registry.npmjs.org/@esbuild/android-x64/-/android-x64-0.18.3.tgz", + "integrity": "sha512-1OkJf8wNX1W5ucbp5HrK+z42b9DINb4ix59oJH/PIsh9cyFMqjgRKtCBXg0zEWhkmP1k3egdfrnS7cDTpLH43g==", "cpu": [ "x64" ], @@ -102,9 +102,9 @@ } }, "node_modules/@esbuild/darwin-arm64": { - "version": "0.18.2", - "resolved": "https://registry.npmjs.org/@esbuild/darwin-arm64/-/darwin-arm64-0.18.2.tgz", - "integrity": "sha512-a3Rkqd0tGVYMEKNy9SstWEdeBmM60l8FVD5o4rmwHr3xO1LbLqtCJSrWGbnf37hevo6m437mURVmpEHOmkXeTA==", + "version": "0.18.3", + "resolved": "https://registry.npmjs.org/@esbuild/darwin-arm64/-/darwin-arm64-0.18.3.tgz", + "integrity": "sha512-57aofORpY7wDAuMs6DeqpmgSnVfZ63RgGbR/BHdOSTqJgYvHDCMY7/o1myFntl3k0YxtLE3WAm56nMf4qy3UDw==", "cpu": [ "arm64" ], @@ -117,9 +117,9 @@ } }, "node_modules/@esbuild/darwin-x64": { - "version": "0.18.2", - "resolved": "https://registry.npmjs.org/@esbuild/darwin-x64/-/darwin-x64-0.18.2.tgz", - "integrity": "sha512-cvH58adz9L10JNsIcgtkWNS/1eutjRTi3rtWz1s3ZhR64BpdmkxJBAXE/UjqybyNAWLhaN8mPJdlYI2f+tQA7g==", + "version": "0.18.3", + "resolved": "https://registry.npmjs.org/@esbuild/darwin-x64/-/darwin-x64-0.18.3.tgz", + "integrity": "sha512-NVBqMnxT9qvgu7Z322LUDlwjh4GDk6wEePyAQnHF9noxik/WvLFmr5v3Vgz5LSvqFducLCxsdmLztKhdpFW0Gg==", "cpu": [ "x64" ], @@ -132,9 +132,9 @@ } }, "node_modules/@esbuild/freebsd-arm64": { - "version": "0.18.2", - "resolved": "https://registry.npmjs.org/@esbuild/freebsd-arm64/-/freebsd-arm64-0.18.2.tgz", - "integrity": "sha512-68rGMGUdgmq+c5IvseCMqY4yaa2CAY/DIILMBA6bEU1caISF7fXnV69B1uU4s3ERuVDcasVVwiAFyNxCtkS6Zg==", + "version": "0.18.3", + "resolved": "https://registry.npmjs.org/@esbuild/freebsd-arm64/-/freebsd-arm64-0.18.3.tgz", + "integrity": "sha512-XiLK1AsCk2wKxN7j8h9GXXCs8FPZhp07U0rnpwRkAVSVGgLaIWYSqpTRzKjAfqJiZlp+XKo1HwsmDdICEKB3Dg==", "cpu": [ "arm64" ], @@ -147,9 +147,9 @@ } }, "node_modules/@esbuild/freebsd-x64": { - "version": "0.18.2", - "resolved": "https://registry.npmjs.org/@esbuild/freebsd-x64/-/freebsd-x64-0.18.2.tgz", - "integrity": "sha512-ZSR9On/rXoYuAtrXo5hYKy7OuZwKZyFh2rr6L3TX4UeR1tWLf84aLyAFt7e0tlRbh4zNgqFx+ePWmsSHw7L9Bw==", + "version": "0.18.3", + "resolved": "https://registry.npmjs.org/@esbuild/freebsd-x64/-/freebsd-x64-0.18.3.tgz", + "integrity": "sha512-xyITfrF0G3l1gwR79hvNCCWKQ/16uK14xNNPFgzjbIqF4EpBvhO6l3jrWxXFUW51z6dVIl2Szh3x3uIbBWzH1Q==", "cpu": [ "x64" ], @@ -162,9 +162,9 @@ } }, "node_modules/@esbuild/linux-arm": { - "version": "0.18.2", - "resolved": "https://registry.npmjs.org/@esbuild/linux-arm/-/linux-arm-0.18.2.tgz", - "integrity": "sha512-jAbA75qJ70T5AOdmw9X8675ppeRfj7j57sOypoZ4mQlfQ/LKF8eoeLzTYVo8+aqLKqeIIl0vQ4hKOB0FyG98Zg==", + "version": "0.18.3", + "resolved": "https://registry.npmjs.org/@esbuild/linux-arm/-/linux-arm-0.18.3.tgz", + "integrity": "sha512-fc/T0QHMzvmnlF+kfD6bHLB8u+17gg13260p/E86yYjVoKNFjonL/+Y0GGQjMbFUas9QijqOa7pcR00a9RNkwg==", "cpu": [ "arm" ], @@ -177,9 +177,9 @@ } }, "node_modules/@esbuild/linux-arm64": { - "version": "0.18.2", - "resolved": "https://registry.npmjs.org/@esbuild/linux-arm64/-/linux-arm64-0.18.2.tgz", - "integrity": "sha512-DFKavAzbu/n9HXWuetxmYN10XnfzW7FgOgpcrGD8eXaiu77KdgB+OVWA83x9FtDYtsoFpfdlDuVFAQFfrhu77A==", + "version": "0.18.3", + "resolved": "https://registry.npmjs.org/@esbuild/linux-arm64/-/linux-arm64-0.18.3.tgz", + "integrity": "sha512-lsKUYVd8L/j2uNs8dhMjMsKC5MHYh77gR9EThu7YCeeFz1XpIkx1I4a7mhoVfPS2VPVD1pMCh+PgxuAHUcEmXw==", "cpu": [ "arm64" ], @@ -192,9 +192,9 @@ } }, "node_modules/@esbuild/linux-ia32": { - "version": "0.18.2", - "resolved": "https://registry.npmjs.org/@esbuild/linux-ia32/-/linux-ia32-0.18.2.tgz", - "integrity": "sha512-VEaK3Z+vJyDwwPsP0sovaEw1foDzrMs7XQNYEIFkOwMjSe2BipKRKUUyrznil0p8qqsK7U8W+T7oNqZpgdnD2Q==", + "version": "0.18.3", + "resolved": "https://registry.npmjs.org/@esbuild/linux-ia32/-/linux-ia32-0.18.3.tgz", + "integrity": "sha512-EyfGWeOwRqK5Xj18vok0qv8IFBZ1/+hKV+cqD44oVhGsxHo9TmPtoSiDrWn8Sa2swq/VuO5Aiog6YPDj81oIkA==", "cpu": [ "ia32" ], @@ -207,9 +207,9 @@ } }, "node_modules/@esbuild/linux-loong64": { - "version": "0.18.2", - "resolved": "https://registry.npmjs.org/@esbuild/linux-loong64/-/linux-loong64-0.18.2.tgz", - "integrity": "sha512-Af1uZdB0oeJo4PW67l9aw94oakSamFxhC6ltC2eDkndozd9QygVNMTF7s7uxTLjo+BJqyVqG9wjmLCYF1o4NmA==", + "version": "0.18.3", + "resolved": "https://registry.npmjs.org/@esbuild/linux-loong64/-/linux-loong64-0.18.3.tgz", + "integrity": "sha512-PwXkcl3t0kSeYH5RuJIeh/fHOzKZd+ZdifAWzpVO+9TLWArutTFBJvOSkTZ3CcqQqNrTj1Qyo6nqE8MQj/a7cQ==", "cpu": [ "loong64" ], @@ -222,9 +222,9 @@ } }, "node_modules/@esbuild/linux-mips64el": { - "version": "0.18.2", - "resolved": "https://registry.npmjs.org/@esbuild/linux-mips64el/-/linux-mips64el-0.18.2.tgz", - "integrity": "sha512-WcTbt61+9dREuOFKXac4Qg+3OuRhLxPL9lmkI2P7fGuq/fWS2qq+AvGGVLMyk+OtXGDjyQolcEDeYlRoOmjRYQ==", + "version": "0.18.3", + "resolved": "https://registry.npmjs.org/@esbuild/linux-mips64el/-/linux-mips64el-0.18.3.tgz", + "integrity": "sha512-CRVkkSXf5GQcq7Am2a2tdIn85oqi/bkjuPvhNqcdeTgI0xgNbqLnEPRy2AEGkRuaJWB5uCX1IC4sqnY8ET14Yg==", "cpu": [ "mips64el" ], @@ -237,9 +237,9 @@ } }, "node_modules/@esbuild/linux-ppc64": { - "version": "0.18.2", - "resolved": "https://registry.npmjs.org/@esbuild/linux-ppc64/-/linux-ppc64-0.18.2.tgz", - "integrity": "sha512-Ov+VHayvCPb52axma6+xm8QDawRjwHscPXedHg4U92DxlhKQ0H+6onRiC3J9kKI50p8pKKypprpCWrRrXjZN7Q==", + "version": "0.18.3", + "resolved": "https://registry.npmjs.org/@esbuild/linux-ppc64/-/linux-ppc64-0.18.3.tgz", + "integrity": "sha512-t7zK1Cheh0xvzfZbimztiE0wGnpV+YRsBg3tefcEBN3O4GzgLu6fFpA5HxEyVm3hHZW1jAC4OhoGEp7C5Ii6Eg==", "cpu": [ "ppc64" ], @@ -252,9 +252,9 @@ } }, "node_modules/@esbuild/linux-riscv64": { - "version": "0.18.2", - "resolved": "https://registry.npmjs.org/@esbuild/linux-riscv64/-/linux-riscv64-0.18.2.tgz", - "integrity": "sha512-qW37zzKKN9C5l5LnVDriOK0eZRzQeixhtrfd5C78PAsTE15GeHU9G0oyT/u/IkNjEBjXWpTZOOHKNbjhrvuL9g==", + "version": "0.18.3", + "resolved": "https://registry.npmjs.org/@esbuild/linux-riscv64/-/linux-riscv64-0.18.3.tgz", + "integrity": "sha512-fUZPtyCYih6y4lDYdSM4Yoax4nS7aH0/XixJStys+9tfp5cAlIAZhEVKOOdeGXmQn0IEyiUtlIsPnfObbeDQfQ==", "cpu": [ "riscv64" ], @@ -267,9 +267,9 @@ } }, "node_modules/@esbuild/linux-s390x": { - "version": "0.18.2", - "resolved": "https://registry.npmjs.org/@esbuild/linux-s390x/-/linux-s390x-0.18.2.tgz", - "integrity": "sha512-izzEFMRO8LaQIlX22+fTgP5I7Os3T51mtAWsRNpZ5pMfQIa9PqtgFAoRcb10DV+/YkH/TMMxQIlevUvDS6E4vw==", + "version": "0.18.3", + "resolved": "https://registry.npmjs.org/@esbuild/linux-s390x/-/linux-s390x-0.18.3.tgz", + "integrity": "sha512-oIcK2LqHWqfMERqjvaKJ3QJmycHn723HsXIv5gH4iGfmePfSj+gi0ZQv2h4bHUg2bs2gJtV0DlIjGhEuvdgxLw==", "cpu": [ "s390x" ], @@ -282,9 +282,9 @@ } }, "node_modules/@esbuild/linux-x64": { - "version": "0.18.2", - "resolved": "https://registry.npmjs.org/@esbuild/linux-x64/-/linux-x64-0.18.2.tgz", - "integrity": "sha512-y5yqQ1ww4FfI9bQ1ZP/0k1rcgA6Ql2/AgzvqpowN0Q5tXDZkCavPdJbFXKrqA43vd1UTXt+AutTHYJ7km6e2Eg==", + "version": "0.18.3", + "resolved": "https://registry.npmjs.org/@esbuild/linux-x64/-/linux-x64-0.18.3.tgz", + "integrity": "sha512-RW9lpfZ6XZ6f5to2DJPvt0f/4RXEW229Xf++quVoW+YbnPrcapIJChtD/AmZ8cK3hglO/hXxJjs21pV0/l7L5w==", "cpu": [ "x64" ], @@ -297,9 +297,9 @@ } }, "node_modules/@esbuild/netbsd-x64": { - "version": "0.18.2", - "resolved": "https://registry.npmjs.org/@esbuild/netbsd-x64/-/netbsd-x64-0.18.2.tgz", - "integrity": "sha512-usNjpKFf83X4o60gdMD47NCblaSZ6DARf31/FyCzxOgnF80mJ+RhDs9RTqgyfH8KyduO5mjgInw9+ct286ayYA==", + "version": "0.18.3", + "resolved": "https://registry.npmjs.org/@esbuild/netbsd-x64/-/netbsd-x64-0.18.3.tgz", + "integrity": "sha512-piZ2oBoaq58pKZvhgdV6PemlL30Uhd9GmmOkIGZYgChwNcyVSSl6iMEJxMzU7x44Lk9q+hJ6a343M/iVEMEvxA==", "cpu": [ "x64" ], @@ -312,9 +312,9 @@ } }, "node_modules/@esbuild/openbsd-x64": { - "version": "0.18.2", - "resolved": "https://registry.npmjs.org/@esbuild/openbsd-x64/-/openbsd-x64-0.18.2.tgz", - "integrity": "sha512-6urzy1+VwcPuhG+5jwHA8lD9E87E5+ey3qKw2EhRS+qUmMxLvfwP8szWC2JHVGZDPEDge6fgn0pBj+y9rxDLwQ==", + "version": "0.18.3", + "resolved": "https://registry.npmjs.org/@esbuild/openbsd-x64/-/openbsd-x64-0.18.3.tgz", + "integrity": "sha512-vaMfouYTz/4tKdQsXDccqhV6wgPEr+hfuxdNU5Pl/vQxYTsqcXv5DYEa5Z1RAxCoua5aEB+Uj5V7VT/bM92wxw==", "cpu": [ "x64" ], @@ -327,9 +327,9 @@ } }, "node_modules/@esbuild/sunos-x64": { - "version": "0.18.2", - "resolved": "https://registry.npmjs.org/@esbuild/sunos-x64/-/sunos-x64-0.18.2.tgz", - "integrity": "sha512-SMZPTACsvpKYAIl9o8nhnmMn6/lp62iMeV/2EBMtj+sW6dXwW9b0cLjihkBv4PG1CCRlwWKPZo43imqZxC95ZA==", + "version": "0.18.3", + "resolved": "https://registry.npmjs.org/@esbuild/sunos-x64/-/sunos-x64-0.18.3.tgz", + "integrity": "sha512-Fa3rNQQ9q1qwy9u2cdDvuGKy3jmPnPPMDdyy/qbn5d395Pb9hjLYiPzX9BozXMPJDlCNofSY7jN3miM9gyAdHA==", "cpu": [ "x64" ], @@ -342,9 +342,9 @@ } }, "node_modules/@esbuild/win32-arm64": { - "version": "0.18.2", - "resolved": "https://registry.npmjs.org/@esbuild/win32-arm64/-/win32-arm64-0.18.2.tgz", - "integrity": "sha512-H2zzjPdzSDNwUnZdZf9/xfm0CYqHFXuenCMAx+tRzIRqWUT6MmZ9/q7722KnAZ6uPpq0RLs7EjCIIfmt6CaRGg==", + "version": "0.18.3", + "resolved": "https://registry.npmjs.org/@esbuild/win32-arm64/-/win32-arm64-0.18.3.tgz", + "integrity": "sha512-LPJC8ub+9uzyC6ygVmp00dAqet1q1DsZ/OldGIIBt+y+Ctd1OfnKNlzQgXK8nxwY1G8fAhklFSeSRRgAUJnR0w==", "cpu": [ "arm64" ], @@ -357,9 +357,9 @@ } }, "node_modules/@esbuild/win32-ia32": { - "version": "0.18.2", - "resolved": "https://registry.npmjs.org/@esbuild/win32-ia32/-/win32-ia32-0.18.2.tgz", - "integrity": "sha512-lfyjTN+FrKgvNvrH7nOLtaz58J/8coZOo4LQwgBMP4D7ZOurhvluXS3GjePLzq9GbWnJDZdKCKbMKhZPPcdJJA==", + "version": "0.18.3", + "resolved": "https://registry.npmjs.org/@esbuild/win32-ia32/-/win32-ia32-0.18.3.tgz", + "integrity": "sha512-WtUyRspyxZR6NTc2HG4xd9Wvz8lP4C6OUY1gAqisrf151HvXIxsK0mfAacFJNS7EN2wvPTgjP+SM8vgBOx5+zA==", "cpu": [ "ia32" ], @@ -372,9 +372,9 @@ } }, "node_modules/@esbuild/win32-x64": { - "version": "0.18.2", - "resolved": "https://registry.npmjs.org/@esbuild/win32-x64/-/win32-x64-0.18.2.tgz", - "integrity": "sha512-Q4nIjqWXjxkELwd7kVepsJxbQ/6ERNsHpjz1j+IKjwSYw+g06U0RQOy5xh848AHvgr9itnGLa3cT2G5t0dBFsw==", + "version": "0.18.3", + "resolved": "https://registry.npmjs.org/@esbuild/win32-x64/-/win32-x64-0.18.3.tgz", + "integrity": "sha512-Z8qCK4BkBm40j5KUM4NrkxYQS0R12cBO1NBVtI4vws6uwh1n/VaNu31Hm+n2cJUWdFbfH57PBghkhm9yLgmPfw==", "cpu": [ "x64" ], @@ -1647,9 +1647,9 @@ } }, "node_modules/esbuild": { - "version": "0.18.2", - "resolved": "https://registry.npmjs.org/esbuild/-/esbuild-0.18.2.tgz", - "integrity": "sha512-1P4sK9gXVcjvrrUjE94Hbo9goU+T6U1sdzLf+JJ+3uI6GEb4e4n3Wrqto9hZHUWabblpT2ifmC61LhZnLyTNFw==", + "version": "0.18.3", + "resolved": "https://registry.npmjs.org/esbuild/-/esbuild-0.18.3.tgz", + "integrity": "sha512-eadWJC4CRpj93+miO5ZBlvCv+m2x6pzyNBznTvUeLFObMmxs1IMd8cCf6qiDVEZuDL6W8W7u+ZNW3GKEfOdDsA==", "hasInstallScript": true, "bin": { "esbuild": "bin/esbuild" @@ -1658,28 +1658,28 @@ "node": ">=12" }, "optionalDependencies": { - "@esbuild/android-arm": "0.18.2", - "@esbuild/android-arm64": "0.18.2", - "@esbuild/android-x64": "0.18.2", - "@esbuild/darwin-arm64": "0.18.2", - "@esbuild/darwin-x64": "0.18.2", - "@esbuild/freebsd-arm64": "0.18.2", - "@esbuild/freebsd-x64": "0.18.2", - "@esbuild/linux-arm": "0.18.2", - "@esbuild/linux-arm64": "0.18.2", - "@esbuild/linux-ia32": "0.18.2", - "@esbuild/linux-loong64": "0.18.2", - "@esbuild/linux-mips64el": "0.18.2", - "@esbuild/linux-ppc64": "0.18.2", - "@esbuild/linux-riscv64": "0.18.2", - "@esbuild/linux-s390x": "0.18.2", - "@esbuild/linux-x64": "0.18.2", - "@esbuild/netbsd-x64": "0.18.2", - "@esbuild/openbsd-x64": "0.18.2", - "@esbuild/sunos-x64": "0.18.2", - "@esbuild/win32-arm64": "0.18.2", - "@esbuild/win32-ia32": "0.18.2", - "@esbuild/win32-x64": "0.18.2" + "@esbuild/android-arm": "0.18.3", + "@esbuild/android-arm64": "0.18.3", + "@esbuild/android-x64": "0.18.3", + "@esbuild/darwin-arm64": "0.18.3", + "@esbuild/darwin-x64": "0.18.3", + "@esbuild/freebsd-arm64": "0.18.3", + "@esbuild/freebsd-x64": "0.18.3", + "@esbuild/linux-arm": "0.18.3", + "@esbuild/linux-arm64": "0.18.3", + "@esbuild/linux-ia32": "0.18.3", + "@esbuild/linux-loong64": "0.18.3", + "@esbuild/linux-mips64el": "0.18.3", + "@esbuild/linux-ppc64": "0.18.3", + "@esbuild/linux-riscv64": "0.18.3", + "@esbuild/linux-s390x": "0.18.3", + "@esbuild/linux-x64": "0.18.3", + "@esbuild/netbsd-x64": "0.18.3", + "@esbuild/openbsd-x64": "0.18.3", + "@esbuild/sunos-x64": "0.18.3", + "@esbuild/win32-arm64": "0.18.3", + "@esbuild/win32-ia32": "0.18.3", + "@esbuild/win32-x64": "0.18.3" } }, "node_modules/escalade": { @@ -6797,135 +6797,135 @@ } }, "@esbuild/android-arm": { - "version": "0.18.2", - "resolved": "https://registry.npmjs.org/@esbuild/android-arm/-/android-arm-0.18.2.tgz", - "integrity": "sha512-YAnQBHlY0IvYtvY0avnXjI8ywW23emEjk5XExqbFmypath+Snq9MgY1IS47rnqBKVSqnl0ElDt221ZgaeRrkXg==", + "version": "0.18.3", + "resolved": "https://registry.npmjs.org/@esbuild/android-arm/-/android-arm-0.18.3.tgz", + "integrity": "sha512-QOn3VIlL6Qv1eHBpQB/s7simaZgGss2ASyxDOwYSLmc6vD0uuizZkuYawHmuLjWEm5wPwp0JQWhbpaYwwGevYw==", "optional": true }, "@esbuild/android-arm64": { - "version": "0.18.2", - "resolved": "https://registry.npmjs.org/@esbuild/android-arm64/-/android-arm64-0.18.2.tgz", - "integrity": "sha512-1Y2pb0hLdmji8I0zBwNsYSDN7zJSQqufgLOuOsrrod00WEAgKywQR5MB/E046Is/YTP4bgcPS4BioaSDBaLaTg==", + "version": "0.18.3", + "resolved": "https://registry.npmjs.org/@esbuild/android-arm64/-/android-arm64-0.18.3.tgz", + "integrity": "sha512-PgabCsoaEEnnOiF6rUhOBXgYoLFIrHWP6mfLOzuQ1oZ1lwBdTL0hp5ivC4K3Kvz3BD8EipjeQo6l0aty3nr4qQ==", "optional": true }, "@esbuild/android-x64": { - "version": "0.18.2", - "resolved": "https://registry.npmjs.org/@esbuild/android-x64/-/android-x64-0.18.2.tgz", - "integrity": "sha512-P047Mh3pj8uYVE3A/B3QDX6nG8dKbHLJ+48R6Y0CRXCJ5PkXJxdHOTaS8SYs6eSR3FFU6/YQ5TishQXVHX7F5A==", + "version": "0.18.3", + "resolved": "https://registry.npmjs.org/@esbuild/android-x64/-/android-x64-0.18.3.tgz", + "integrity": "sha512-1OkJf8wNX1W5ucbp5HrK+z42b9DINb4ix59oJH/PIsh9cyFMqjgRKtCBXg0zEWhkmP1k3egdfrnS7cDTpLH43g==", "optional": true }, "@esbuild/darwin-arm64": { - "version": "0.18.2", - "resolved": "https://registry.npmjs.org/@esbuild/darwin-arm64/-/darwin-arm64-0.18.2.tgz", - "integrity": "sha512-a3Rkqd0tGVYMEKNy9SstWEdeBmM60l8FVD5o4rmwHr3xO1LbLqtCJSrWGbnf37hevo6m437mURVmpEHOmkXeTA==", + "version": "0.18.3", + "resolved": "https://registry.npmjs.org/@esbuild/darwin-arm64/-/darwin-arm64-0.18.3.tgz", + "integrity": "sha512-57aofORpY7wDAuMs6DeqpmgSnVfZ63RgGbR/BHdOSTqJgYvHDCMY7/o1myFntl3k0YxtLE3WAm56nMf4qy3UDw==", "optional": true }, "@esbuild/darwin-x64": { - "version": "0.18.2", - "resolved": "https://registry.npmjs.org/@esbuild/darwin-x64/-/darwin-x64-0.18.2.tgz", - "integrity": "sha512-cvH58adz9L10JNsIcgtkWNS/1eutjRTi3rtWz1s3ZhR64BpdmkxJBAXE/UjqybyNAWLhaN8mPJdlYI2f+tQA7g==", + "version": "0.18.3", + "resolved": "https://registry.npmjs.org/@esbuild/darwin-x64/-/darwin-x64-0.18.3.tgz", + "integrity": "sha512-NVBqMnxT9qvgu7Z322LUDlwjh4GDk6wEePyAQnHF9noxik/WvLFmr5v3Vgz5LSvqFducLCxsdmLztKhdpFW0Gg==", "optional": true }, "@esbuild/freebsd-arm64": { - "version": "0.18.2", - "resolved": "https://registry.npmjs.org/@esbuild/freebsd-arm64/-/freebsd-arm64-0.18.2.tgz", - "integrity": "sha512-68rGMGUdgmq+c5IvseCMqY4yaa2CAY/DIILMBA6bEU1caISF7fXnV69B1uU4s3ERuVDcasVVwiAFyNxCtkS6Zg==", + "version": "0.18.3", + "resolved": "https://registry.npmjs.org/@esbuild/freebsd-arm64/-/freebsd-arm64-0.18.3.tgz", + "integrity": "sha512-XiLK1AsCk2wKxN7j8h9GXXCs8FPZhp07U0rnpwRkAVSVGgLaIWYSqpTRzKjAfqJiZlp+XKo1HwsmDdICEKB3Dg==", "optional": true }, "@esbuild/freebsd-x64": { - "version": "0.18.2", - "resolved": "https://registry.npmjs.org/@esbuild/freebsd-x64/-/freebsd-x64-0.18.2.tgz", - "integrity": "sha512-ZSR9On/rXoYuAtrXo5hYKy7OuZwKZyFh2rr6L3TX4UeR1tWLf84aLyAFt7e0tlRbh4zNgqFx+ePWmsSHw7L9Bw==", + "version": "0.18.3", + "resolved": "https://registry.npmjs.org/@esbuild/freebsd-x64/-/freebsd-x64-0.18.3.tgz", + "integrity": "sha512-xyITfrF0G3l1gwR79hvNCCWKQ/16uK14xNNPFgzjbIqF4EpBvhO6l3jrWxXFUW51z6dVIl2Szh3x3uIbBWzH1Q==", "optional": true }, "@esbuild/linux-arm": { - "version": "0.18.2", - "resolved": "https://registry.npmjs.org/@esbuild/linux-arm/-/linux-arm-0.18.2.tgz", - "integrity": "sha512-jAbA75qJ70T5AOdmw9X8675ppeRfj7j57sOypoZ4mQlfQ/LKF8eoeLzTYVo8+aqLKqeIIl0vQ4hKOB0FyG98Zg==", + "version": "0.18.3", + "resolved": "https://registry.npmjs.org/@esbuild/linux-arm/-/linux-arm-0.18.3.tgz", + "integrity": "sha512-fc/T0QHMzvmnlF+kfD6bHLB8u+17gg13260p/E86yYjVoKNFjonL/+Y0GGQjMbFUas9QijqOa7pcR00a9RNkwg==", "optional": true }, "@esbuild/linux-arm64": { - "version": "0.18.2", - "resolved": "https://registry.npmjs.org/@esbuild/linux-arm64/-/linux-arm64-0.18.2.tgz", - "integrity": "sha512-DFKavAzbu/n9HXWuetxmYN10XnfzW7FgOgpcrGD8eXaiu77KdgB+OVWA83x9FtDYtsoFpfdlDuVFAQFfrhu77A==", + "version": "0.18.3", + "resolved": "https://registry.npmjs.org/@esbuild/linux-arm64/-/linux-arm64-0.18.3.tgz", + "integrity": "sha512-lsKUYVd8L/j2uNs8dhMjMsKC5MHYh77gR9EThu7YCeeFz1XpIkx1I4a7mhoVfPS2VPVD1pMCh+PgxuAHUcEmXw==", "optional": true }, "@esbuild/linux-ia32": { - "version": "0.18.2", - "resolved": "https://registry.npmjs.org/@esbuild/linux-ia32/-/linux-ia32-0.18.2.tgz", - "integrity": "sha512-VEaK3Z+vJyDwwPsP0sovaEw1foDzrMs7XQNYEIFkOwMjSe2BipKRKUUyrznil0p8qqsK7U8W+T7oNqZpgdnD2Q==", + "version": "0.18.3", + "resolved": "https://registry.npmjs.org/@esbuild/linux-ia32/-/linux-ia32-0.18.3.tgz", + "integrity": "sha512-EyfGWeOwRqK5Xj18vok0qv8IFBZ1/+hKV+cqD44oVhGsxHo9TmPtoSiDrWn8Sa2swq/VuO5Aiog6YPDj81oIkA==", "optional": true }, "@esbuild/linux-loong64": { - "version": "0.18.2", - "resolved": "https://registry.npmjs.org/@esbuild/linux-loong64/-/linux-loong64-0.18.2.tgz", - "integrity": "sha512-Af1uZdB0oeJo4PW67l9aw94oakSamFxhC6ltC2eDkndozd9QygVNMTF7s7uxTLjo+BJqyVqG9wjmLCYF1o4NmA==", + "version": "0.18.3", + "resolved": "https://registry.npmjs.org/@esbuild/linux-loong64/-/linux-loong64-0.18.3.tgz", + "integrity": "sha512-PwXkcl3t0kSeYH5RuJIeh/fHOzKZd+ZdifAWzpVO+9TLWArutTFBJvOSkTZ3CcqQqNrTj1Qyo6nqE8MQj/a7cQ==", "optional": true }, "@esbuild/linux-mips64el": { - "version": "0.18.2", - "resolved": "https://registry.npmjs.org/@esbuild/linux-mips64el/-/linux-mips64el-0.18.2.tgz", - "integrity": "sha512-WcTbt61+9dREuOFKXac4Qg+3OuRhLxPL9lmkI2P7fGuq/fWS2qq+AvGGVLMyk+OtXGDjyQolcEDeYlRoOmjRYQ==", + "version": "0.18.3", + "resolved": "https://registry.npmjs.org/@esbuild/linux-mips64el/-/linux-mips64el-0.18.3.tgz", + "integrity": "sha512-CRVkkSXf5GQcq7Am2a2tdIn85oqi/bkjuPvhNqcdeTgI0xgNbqLnEPRy2AEGkRuaJWB5uCX1IC4sqnY8ET14Yg==", "optional": true }, "@esbuild/linux-ppc64": { - "version": "0.18.2", - "resolved": "https://registry.npmjs.org/@esbuild/linux-ppc64/-/linux-ppc64-0.18.2.tgz", - "integrity": "sha512-Ov+VHayvCPb52axma6+xm8QDawRjwHscPXedHg4U92DxlhKQ0H+6onRiC3J9kKI50p8pKKypprpCWrRrXjZN7Q==", + "version": "0.18.3", + "resolved": "https://registry.npmjs.org/@esbuild/linux-ppc64/-/linux-ppc64-0.18.3.tgz", + "integrity": "sha512-t7zK1Cheh0xvzfZbimztiE0wGnpV+YRsBg3tefcEBN3O4GzgLu6fFpA5HxEyVm3hHZW1jAC4OhoGEp7C5Ii6Eg==", "optional": true }, "@esbuild/linux-riscv64": { - "version": "0.18.2", - "resolved": "https://registry.npmjs.org/@esbuild/linux-riscv64/-/linux-riscv64-0.18.2.tgz", - "integrity": "sha512-qW37zzKKN9C5l5LnVDriOK0eZRzQeixhtrfd5C78PAsTE15GeHU9G0oyT/u/IkNjEBjXWpTZOOHKNbjhrvuL9g==", + "version": "0.18.3", + "resolved": "https://registry.npmjs.org/@esbuild/linux-riscv64/-/linux-riscv64-0.18.3.tgz", + "integrity": "sha512-fUZPtyCYih6y4lDYdSM4Yoax4nS7aH0/XixJStys+9tfp5cAlIAZhEVKOOdeGXmQn0IEyiUtlIsPnfObbeDQfQ==", "optional": true }, "@esbuild/linux-s390x": { - "version": "0.18.2", - "resolved": "https://registry.npmjs.org/@esbuild/linux-s390x/-/linux-s390x-0.18.2.tgz", - "integrity": "sha512-izzEFMRO8LaQIlX22+fTgP5I7Os3T51mtAWsRNpZ5pMfQIa9PqtgFAoRcb10DV+/YkH/TMMxQIlevUvDS6E4vw==", + "version": "0.18.3", + "resolved": "https://registry.npmjs.org/@esbuild/linux-s390x/-/linux-s390x-0.18.3.tgz", + "integrity": "sha512-oIcK2LqHWqfMERqjvaKJ3QJmycHn723HsXIv5gH4iGfmePfSj+gi0ZQv2h4bHUg2bs2gJtV0DlIjGhEuvdgxLw==", "optional": true }, "@esbuild/linux-x64": { - "version": "0.18.2", - "resolved": "https://registry.npmjs.org/@esbuild/linux-x64/-/linux-x64-0.18.2.tgz", - "integrity": "sha512-y5yqQ1ww4FfI9bQ1ZP/0k1rcgA6Ql2/AgzvqpowN0Q5tXDZkCavPdJbFXKrqA43vd1UTXt+AutTHYJ7km6e2Eg==", + "version": "0.18.3", + "resolved": "https://registry.npmjs.org/@esbuild/linux-x64/-/linux-x64-0.18.3.tgz", + "integrity": "sha512-RW9lpfZ6XZ6f5to2DJPvt0f/4RXEW229Xf++quVoW+YbnPrcapIJChtD/AmZ8cK3hglO/hXxJjs21pV0/l7L5w==", "optional": true }, "@esbuild/netbsd-x64": { - "version": "0.18.2", - "resolved": "https://registry.npmjs.org/@esbuild/netbsd-x64/-/netbsd-x64-0.18.2.tgz", - "integrity": "sha512-usNjpKFf83X4o60gdMD47NCblaSZ6DARf31/FyCzxOgnF80mJ+RhDs9RTqgyfH8KyduO5mjgInw9+ct286ayYA==", + "version": "0.18.3", + "resolved": "https://registry.npmjs.org/@esbuild/netbsd-x64/-/netbsd-x64-0.18.3.tgz", + "integrity": "sha512-piZ2oBoaq58pKZvhgdV6PemlL30Uhd9GmmOkIGZYgChwNcyVSSl6iMEJxMzU7x44Lk9q+hJ6a343M/iVEMEvxA==", "optional": true }, "@esbuild/openbsd-x64": { - "version": "0.18.2", - "resolved": "https://registry.npmjs.org/@esbuild/openbsd-x64/-/openbsd-x64-0.18.2.tgz", - "integrity": "sha512-6urzy1+VwcPuhG+5jwHA8lD9E87E5+ey3qKw2EhRS+qUmMxLvfwP8szWC2JHVGZDPEDge6fgn0pBj+y9rxDLwQ==", + "version": "0.18.3", + "resolved": "https://registry.npmjs.org/@esbuild/openbsd-x64/-/openbsd-x64-0.18.3.tgz", + "integrity": "sha512-vaMfouYTz/4tKdQsXDccqhV6wgPEr+hfuxdNU5Pl/vQxYTsqcXv5DYEa5Z1RAxCoua5aEB+Uj5V7VT/bM92wxw==", "optional": true }, "@esbuild/sunos-x64": { - "version": "0.18.2", - "resolved": "https://registry.npmjs.org/@esbuild/sunos-x64/-/sunos-x64-0.18.2.tgz", - "integrity": "sha512-SMZPTACsvpKYAIl9o8nhnmMn6/lp62iMeV/2EBMtj+sW6dXwW9b0cLjihkBv4PG1CCRlwWKPZo43imqZxC95ZA==", + "version": "0.18.3", + "resolved": "https://registry.npmjs.org/@esbuild/sunos-x64/-/sunos-x64-0.18.3.tgz", + "integrity": "sha512-Fa3rNQQ9q1qwy9u2cdDvuGKy3jmPnPPMDdyy/qbn5d395Pb9hjLYiPzX9BozXMPJDlCNofSY7jN3miM9gyAdHA==", "optional": true }, "@esbuild/win32-arm64": { - "version": "0.18.2", - "resolved": "https://registry.npmjs.org/@esbuild/win32-arm64/-/win32-arm64-0.18.2.tgz", - "integrity": "sha512-H2zzjPdzSDNwUnZdZf9/xfm0CYqHFXuenCMAx+tRzIRqWUT6MmZ9/q7722KnAZ6uPpq0RLs7EjCIIfmt6CaRGg==", + "version": "0.18.3", + "resolved": "https://registry.npmjs.org/@esbuild/win32-arm64/-/win32-arm64-0.18.3.tgz", + "integrity": "sha512-LPJC8ub+9uzyC6ygVmp00dAqet1q1DsZ/OldGIIBt+y+Ctd1OfnKNlzQgXK8nxwY1G8fAhklFSeSRRgAUJnR0w==", "optional": true }, "@esbuild/win32-ia32": { - "version": "0.18.2", - "resolved": "https://registry.npmjs.org/@esbuild/win32-ia32/-/win32-ia32-0.18.2.tgz", - "integrity": "sha512-lfyjTN+FrKgvNvrH7nOLtaz58J/8coZOo4LQwgBMP4D7ZOurhvluXS3GjePLzq9GbWnJDZdKCKbMKhZPPcdJJA==", + "version": "0.18.3", + "resolved": "https://registry.npmjs.org/@esbuild/win32-ia32/-/win32-ia32-0.18.3.tgz", + "integrity": "sha512-WtUyRspyxZR6NTc2HG4xd9Wvz8lP4C6OUY1gAqisrf151HvXIxsK0mfAacFJNS7EN2wvPTgjP+SM8vgBOx5+zA==", "optional": true }, "@esbuild/win32-x64": { - "version": "0.18.2", - "resolved": "https://registry.npmjs.org/@esbuild/win32-x64/-/win32-x64-0.18.2.tgz", - "integrity": "sha512-Q4nIjqWXjxkELwd7kVepsJxbQ/6ERNsHpjz1j+IKjwSYw+g06U0RQOy5xh848AHvgr9itnGLa3cT2G5t0dBFsw==", + "version": "0.18.3", + "resolved": "https://registry.npmjs.org/@esbuild/win32-x64/-/win32-x64-0.18.3.tgz", + "integrity": "sha512-Z8qCK4BkBm40j5KUM4NrkxYQS0R12cBO1NBVtI4vws6uwh1n/VaNu31Hm+n2cJUWdFbfH57PBghkhm9yLgmPfw==", "optional": true }, "@jridgewell/gen-mapping": { @@ -7896,32 +7896,32 @@ "integrity": "sha512-V0hjH4dGPh9Ao5p0MoRY6BVqtwCjhz6vI5LT8AJ55H+4g9/4vbHx1I54fS0XuclLhDHArPQCiMjDxjaL8fPxhw==" }, "esbuild": { - "version": "0.18.2", - "resolved": "https://registry.npmjs.org/esbuild/-/esbuild-0.18.2.tgz", - "integrity": "sha512-1P4sK9gXVcjvrrUjE94Hbo9goU+T6U1sdzLf+JJ+3uI6GEb4e4n3Wrqto9hZHUWabblpT2ifmC61LhZnLyTNFw==", - "requires": { - "@esbuild/android-arm": "0.18.2", - "@esbuild/android-arm64": "0.18.2", - "@esbuild/android-x64": "0.18.2", - "@esbuild/darwin-arm64": "0.18.2", - "@esbuild/darwin-x64": "0.18.2", - "@esbuild/freebsd-arm64": "0.18.2", - "@esbuild/freebsd-x64": "0.18.2", - "@esbuild/linux-arm": "0.18.2", - "@esbuild/linux-arm64": "0.18.2", - "@esbuild/linux-ia32": "0.18.2", - "@esbuild/linux-loong64": "0.18.2", - "@esbuild/linux-mips64el": "0.18.2", - "@esbuild/linux-ppc64": "0.18.2", - "@esbuild/linux-riscv64": "0.18.2", - "@esbuild/linux-s390x": "0.18.2", - "@esbuild/linux-x64": "0.18.2", - "@esbuild/netbsd-x64": "0.18.2", - "@esbuild/openbsd-x64": "0.18.2", - "@esbuild/sunos-x64": "0.18.2", - "@esbuild/win32-arm64": "0.18.2", - "@esbuild/win32-ia32": "0.18.2", - "@esbuild/win32-x64": "0.18.2" + "version": "0.18.3", + "resolved": "https://registry.npmjs.org/esbuild/-/esbuild-0.18.3.tgz", + "integrity": "sha512-eadWJC4CRpj93+miO5ZBlvCv+m2x6pzyNBznTvUeLFObMmxs1IMd8cCf6qiDVEZuDL6W8W7u+ZNW3GKEfOdDsA==", + "requires": { + "@esbuild/android-arm": "0.18.3", + "@esbuild/android-arm64": "0.18.3", + "@esbuild/android-x64": "0.18.3", + "@esbuild/darwin-arm64": "0.18.3", + "@esbuild/darwin-x64": "0.18.3", + "@esbuild/freebsd-arm64": "0.18.3", + "@esbuild/freebsd-x64": "0.18.3", + "@esbuild/linux-arm": "0.18.3", + "@esbuild/linux-arm64": "0.18.3", + "@esbuild/linux-ia32": "0.18.3", + "@esbuild/linux-loong64": "0.18.3", + "@esbuild/linux-mips64el": "0.18.3", + "@esbuild/linux-ppc64": "0.18.3", + "@esbuild/linux-riscv64": "0.18.3", + "@esbuild/linux-s390x": "0.18.3", + "@esbuild/linux-x64": "0.18.3", + "@esbuild/netbsd-x64": "0.18.3", + "@esbuild/openbsd-x64": "0.18.3", + "@esbuild/sunos-x64": "0.18.3", + "@esbuild/win32-arm64": "0.18.3", + "@esbuild/win32-ia32": "0.18.3", + "@esbuild/win32-x64": "0.18.3" } }, "escalade": { diff --git a/package.json b/package.json index 1a630ad..55711a0 100644 --- a/package.json +++ b/package.json @@ -23,7 +23,7 @@ "any-date-parser": "^1.5.4", "browserslist": "^4.21.7", "cheerio": "^1.0.0-rc.12", - "esbuild": "^0.18.2", + "esbuild": "^0.18.3", "fs-cheerio": "^3.0.0", "inline-source": "^8.0.2", "jsdom": "^22.1.0", diff --git a/ts/form.ts b/ts/form.ts index 9688628..31cdf0d 100644 --- a/ts/form.ts +++ b/ts/form.ts @@ -32,6 +32,8 @@ interface formWindow extends Window { userExpiryMessage: string; emailRequired: boolean; captcha: boolean; + reCAPTCHA: boolean; + reCAPTCHASiteKey: string; } loadLangSelector("form"); @@ -263,7 +265,7 @@ let prevCaptcha = ""; function baseValidator(oncomplete: (valid: boolean) => void): void { let captchaChecked = false; let captchaChange = false; - if (window.captcha) { + if (window.captcha && !window.reCAPTCHA) { captchaChange = captchaInput.value != prevCaptcha; if (captchaChange) { prevCaptcha = captchaInput.value; @@ -305,7 +307,7 @@ function baseValidator(oncomplete: (valid: boolean) => void): void { oncomplete(false); return; } - if (window.captcha) { + if (window.captcha && !window.reCAPTCHA) { if (!captchaChange) { oncomplete(captchaVerified); 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); var requirements = r[0]; var validatorFunc = r[1] as () => void; @@ -361,7 +378,7 @@ const genCaptcha = () => { }); }; -if (window.captcha) { +if (window.captcha && !window.reCAPTCHA) { genCaptcha(); (document.getElementById("captcha-regen") as HTMLSpanElement).onclick = genCaptcha; captchaInput.onkeyup = validatorFunc; @@ -369,7 +386,7 @@ if (window.captcha) { const create = (event: SubmitEvent) => { event.preventDefault(); - if (window.captcha && !captchaVerified) { + if (window.captcha && !window.reCAPTCHA && !captchaVerified) { } toggleLoader(submitSpan); @@ -401,8 +418,12 @@ const create = (event: SubmitEvent) => { } } if (window.captcha) { - send.captcha_id = captchaID; - send.captcha_text = captchaInput.value; + if (window.reCAPTCHA) { + send.captcha_text = grecaptcha.getResponse(); + } else { + send.captcha_id = captchaID; + send.captcha_text = captchaInput.value; + } } _post("/newUser", send, (req: XMLHttpRequest) => { if (req.readyState == 4) { diff --git a/views.go b/views.go index 6f89e27..ac07c91 100644 --- a/views.go +++ b/views.go @@ -1,9 +1,12 @@ package main import ( + "encoding/json" "html/template" + "io" "io/fs" "net/http" + "net/url" "strings" "time" @@ -323,17 +326,63 @@ func (app *appContext) GenCaptcha(gc *gin.Context) { } func (app *appContext) verifyCaptcha(code, id, text string) bool { - inv, ok := app.storage.invites[code] - if !ok || inv.Captchas == nil { - app.debug.Printf("Couldn't find invite \"%s\"", code) + reCAPTCHA := app.config.Section("captcha").Key("recaptcha").MustBool(false) + if !reCAPTCHA { + // internal CAPTCHA + inv, ok := app.storage.invites[code] + if !ok || inv.Captchas == nil { + app.debug.Printf("Couldn't find invite \"%s\"", code) + return false + } + c, ok := inv.Captchas[id] + if !ok { + app.debug.Printf("Couldn't find Captcha \"%s\"", id) + return false + } + 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 } - c, ok := inv.Captchas[id] - if !ok { - app.debug.Printf("Couldn't find Captcha \"%s\"", id) + 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 } - return strings.ToLower(c.Text) == strings.ToLower(text) + + 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. @@ -497,6 +546,8 @@ func (app *appContext) InviteProxy(gc *gin.Context) { "matrixEnabled": matrix, "emailRequired": app.config.Section("email").Key("required").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 { data["telegramPIN"] = app.telegram.NewAuthToken()