Add very simple CAPTCHA mechanism
This commit is contained in:
parent
f6dea3e283
commit
d0e05cc955
|
@ -1,7 +1,7 @@
|
||||||
{
|
{
|
||||||
"name": "fwdekker/death-notifier",
|
"name": "fwdekker/death-notifier",
|
||||||
"description": "Get notified when a famous person dies.",
|
"description": "Get notified when a famous person dies.",
|
||||||
"version": "0.19.15", "_comment_version": "Also update version in `package.json`!",
|
"version": "0.19.16", "_comment_version": "Also update version in `package.json`!",
|
||||||
"type": "project",
|
"type": "project",
|
||||||
"license": "MIT",
|
"license": "MIT",
|
||||||
"homepage": "https://git.fwdekker.com/tools/death-notifier",
|
"homepage": "https://git.fwdekker.com/tools/death-notifier",
|
||||||
|
|
Binary file not shown.
Binary file not shown.
|
@ -1,6 +1,6 @@
|
||||||
{
|
{
|
||||||
"name": "death-notifier",
|
"name": "death-notifier",
|
||||||
"version": "0.19.15", "_comment_version": "Also update version in `composer.json`!",
|
"version": "0.19.16", "_comment_version": "Also update version in `composer.json`!",
|
||||||
"description": "Get notified when a famous person dies.",
|
"description": "Get notified when a famous person dies.",
|
||||||
"author": "Florine W. Dekker",
|
"author": "Florine W. Dekker",
|
||||||
"browser": "dist/bundle.js",
|
"browser": "dist/bundle.js",
|
||||||
|
|
|
@ -148,6 +148,11 @@
|
||||||
<label for="register-password-toggle">Show password</label>
|
<label for="register-password-toggle">Show password</label>
|
||||||
<br /><br />
|
<br /><br />
|
||||||
|
|
||||||
|
<label for="register-captcha">Write the word "pride"</label>
|
||||||
|
<input id="register-captcha" name="captcha" />
|
||||||
|
<small id="register-captcha-hint" data-hint-for="register-captcha"
|
||||||
|
data-hint="To prove that you are probably not a robot."></small>
|
||||||
|
|
||||||
<button id="register-submit">Create account</button>
|
<button id="register-submit">Create account</button>
|
||||||
</form>
|
</form>
|
||||||
</div>
|
</div>
|
||||||
|
@ -349,7 +354,6 @@
|
||||||
<label for="update-password-password-new">New password</label>
|
<label for="update-password-password-new">New password</label>
|
||||||
<input id="update-password-password-new" type="password" name="password_new"
|
<input id="update-password-password-new" type="password" name="password_new"
|
||||||
autocomplete="new-password" />
|
autocomplete="new-password" />
|
||||||
<!-- TODO: Add password strength indicator -->
|
|
||||||
<small id="update-password-password-new-hint" data-hint-for="update-password-password-new"
|
<small id="update-password-password-new-hint" data-hint-for="update-password-password-new"
|
||||||
data-hint="Use at least 8 characters."></small>
|
data-hint="Use at least 8 characters."></small>
|
||||||
|
|
||||||
|
|
|
@ -350,7 +350,8 @@ doAfterLoad(() => {
|
||||||
action: "register",
|
action: "register",
|
||||||
token: csrfToken,
|
token: csrfToken,
|
||||||
email: $("#register-email").value,
|
email: $("#register-email").value,
|
||||||
password: $("#register-password").value
|
password: $("#register-password").value,
|
||||||
|
captcha: $("#register-captcha").value,
|
||||||
},
|
},
|
||||||
registerForm,
|
registerForm,
|
||||||
() => {
|
() => {
|
||||||
|
|
|
@ -6,6 +6,7 @@ use com\fwdekker\deathnotifier\Action;
|
||||||
use com\fwdekker\deathnotifier\Config;
|
use com\fwdekker\deathnotifier\Config;
|
||||||
use com\fwdekker\deathnotifier\mailer\Email;
|
use com\fwdekker\deathnotifier\mailer\Email;
|
||||||
use com\fwdekker\deathnotifier\mailer\EmailQueue;
|
use com\fwdekker\deathnotifier\mailer\EmailQueue;
|
||||||
|
use com\fwdekker\deathnotifier\validation\EqualsRule;
|
||||||
use com\fwdekker\deathnotifier\validation\HasStringLengthRule;
|
use com\fwdekker\deathnotifier\validation\HasStringLengthRule;
|
||||||
use com\fwdekker\deathnotifier\validation\InvalidTypeException;
|
use com\fwdekker\deathnotifier\validation\InvalidTypeException;
|
||||||
use com\fwdekker\deathnotifier\validation\InvalidValueException;
|
use com\fwdekker\deathnotifier\validation\InvalidValueException;
|
||||||
|
@ -64,6 +65,10 @@ class RegisterAction extends Action
|
||||||
"token" => [new IsValidCsrfTokenRule()],
|
"token" => [new IsValidCsrfTokenRule()],
|
||||||
"email" => [new IsEmailRule()],
|
"email" => [new IsEmailRule()],
|
||||||
"password" => [new HasStringLengthRule(UserList::MIN_PASSWORD_LENGTH, UserList::MAX_PASSWORD_LENGTH)],
|
"password" => [new HasStringLengthRule(UserList::MIN_PASSWORD_LENGTH, UserList::MAX_PASSWORD_LENGTH)],
|
||||||
|
"captcha" => [new EqualsRule(
|
||||||
|
"pride",
|
||||||
|
"Enter the word \"pride\" to prove that you are probably not a robot."
|
||||||
|
)],
|
||||||
]))->check($inputs);
|
]))->check($inputs);
|
||||||
|
|
||||||
$this->user_list->transaction(function () use ($inputs) {
|
$this->user_list->transaction(function () use ($inputs) {
|
||||||
|
|
|
@ -0,0 +1,57 @@
|
||||||
|
<?php
|
||||||
|
|
||||||
|
namespace com\fwdekker\deathnotifier\validation;
|
||||||
|
|
||||||
|
use com\fwdekker\deathnotifier\Config;
|
||||||
|
use com\fwdekker\deathnotifier\IllegalStateError;
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Validates that the input equals a pre-defined string.
|
||||||
|
*/
|
||||||
|
class EqualsRule extends Rule
|
||||||
|
{
|
||||||
|
/**
|
||||||
|
* @var string the string that the input should equal
|
||||||
|
*/
|
||||||
|
private readonly string $expected;
|
||||||
|
/**
|
||||||
|
* @var string the message that is returned if the input is incorrect
|
||||||
|
*/
|
||||||
|
private readonly string $message_if_incorrect;
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Constructs a new `EqualsRule`.
|
||||||
|
*
|
||||||
|
* @param string $expected the string that the input should equal
|
||||||
|
* @param string $message_if_incorrect the message that is returned if the input is incorrect
|
||||||
|
*/
|
||||||
|
public function __construct(string $expected, string $message_if_incorrect)
|
||||||
|
{
|
||||||
|
$this->expected = $expected;
|
||||||
|
$this->message_if_incorrect = $message_if_incorrect;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Validates that the input equals the CLI password.
|
||||||
|
*
|
||||||
|
* @param array<int|string, mixed> $inputs the list of inputs in which the value at {@see $key} should be checked
|
||||||
|
* @param string $key the key in {@see $inputs} of the input to check
|
||||||
|
* @return void if the checked input equals the CLI password
|
||||||
|
* @throws InvalidTypeException if the CLI password is a blank string, if the CLI password is at its default
|
||||||
|
* value, or if the checked input is not set
|
||||||
|
* @throws InvalidValueException if the checked input does not equal the CLI password
|
||||||
|
*/
|
||||||
|
public function check(array $inputs, string $key): void
|
||||||
|
{
|
||||||
|
if (!isset($inputs[$key]))
|
||||||
|
throw new InvalidTypeException("Required input '$key' not set.");
|
||||||
|
if (!is_string($inputs[$key]))
|
||||||
|
throw new InvalidTypeException("Input '$key' should be string, but is " . gettype($inputs[$key]) . ".");
|
||||||
|
|
||||||
|
if ($inputs[$key] !== $this->expected)
|
||||||
|
throw new InvalidValueException($this->message_if_incorrect, $key);
|
||||||
|
}
|
||||||
|
}
|
|
@ -0,0 +1,25 @@
|
||||||
|
<?php
|
||||||
|
|
||||||
|
namespace com\fwdekker\deathnotifier\validation;
|
||||||
|
|
||||||
|
use InvalidArgumentException;
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Unit tests for {@see EqualsRule}.
|
||||||
|
*/
|
||||||
|
class EqualsRuleTest extends RuleTest
|
||||||
|
{
|
||||||
|
public function check_provider(): array
|
||||||
|
{
|
||||||
|
$type = InvalidTypeException::class;
|
||||||
|
$value = InvalidValueException::class;
|
||||||
|
|
||||||
|
return [
|
||||||
|
"exception if input is not set" => [new EqualsRule("word", "message"), null, $type, "Required input 'key' not set."],
|
||||||
|
"exception if input is not a string" => [new EqualsRule("word", "message"), 738, $type, "Input 'key' should be string, but is integer."],
|
||||||
|
"exception with custom message if input is incorrect" => [new EqualsRule("word", "message"), "incorrect", $value, "message"],
|
||||||
|
"no exception if input equals expected phrase" => [new EqualsRule("word", "message"), "word", null, null],
|
||||||
|
];
|
||||||
|
}
|
||||||
|
}
|
Loading…
Reference in New Issue