Implement adding aliases for accounts
This commit is contained in:
parent
19b8075e3c
commit
37ada99f74
|
|
@ -123,6 +123,11 @@ button {
|
||||||
color: gray;
|
color: gray;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
.margin_vertical_1rem {
|
||||||
|
margin-top: 1rem;
|
||||||
|
margin-bottom: 1rem;
|
||||||
|
}
|
||||||
|
|
||||||
/* -- Tables -- */
|
/* -- Tables -- */
|
||||||
|
|
||||||
table td, table th {
|
table td, table th {
|
||||||
|
|
|
||||||
|
|
@ -34,22 +34,27 @@ abstract class FormData
|
||||||
|
|
||||||
// Input validation - Application specific validators
|
// Input validation - Application specific validators
|
||||||
|
|
||||||
protected static function validateUsername(string $username, bool $required = true): ?string
|
protected static function validateUsername(string $username, bool $required = true, string $fieldName = 'Username'): ?string
|
||||||
{
|
{
|
||||||
if (!$required && $username === '') {
|
if (!$required && $username === '') {
|
||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
|
|
||||||
$username = strtolower(
|
$username = strtolower(
|
||||||
self::validateString($username, 3, 100, 'Username')
|
self::validateString($username, 3, 100, $fieldName)
|
||||||
);
|
);
|
||||||
|
|
||||||
if (!preg_match('/^[a-z0-9._+-]+@[a-z0-9.-]+$/', $username) || preg_match('/^\\.|\\.\\.|\\.@|@\\.|\\.$/', $username)) {
|
if (!preg_match('/^[a-z0-9._+-]+@[a-z0-9.-]+$/', $username) || preg_match('/^\\.|\\.\\.|\\.@|@\\.|\\.$/', $username)) {
|
||||||
throw new InputValidationError('Username is not valid (must be a valid mail address).');
|
throw new InputValidationError("$fieldName is not valid (must be a valid mail address).");
|
||||||
}
|
}
|
||||||
return $username;
|
return $username;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
protected static function validateAliasAddress(string $aliasAddress): string
|
||||||
|
{
|
||||||
|
return self::validateUsername($aliasAddress, true, 'Alias address');
|
||||||
|
}
|
||||||
|
|
||||||
protected static function validatePassword(string $password, string $passwordRepeat, bool $required = true): ?string
|
protected static function validatePassword(string $password, string $passwordRepeat, bool $required = true): ?string
|
||||||
{
|
{
|
||||||
if (!$required && $password === '' && $passwordRepeat === '') {
|
if (!$required && $password === '' && $passwordRepeat === '') {
|
||||||
|
|
|
||||||
|
|
@ -0,0 +1,28 @@
|
||||||
|
<?php
|
||||||
|
declare(strict_types=1);
|
||||||
|
|
||||||
|
namespace MailAccountAdmin\Frontend\Accounts;
|
||||||
|
|
||||||
|
use MailAccountAdmin\Common\FormData;
|
||||||
|
|
||||||
|
class AccountAddAliasData extends FormData
|
||||||
|
{
|
||||||
|
private string $aliasAddress;
|
||||||
|
|
||||||
|
private function __construct(string $aliasAddress)
|
||||||
|
{
|
||||||
|
$this->aliasAddress = $aliasAddress;
|
||||||
|
}
|
||||||
|
|
||||||
|
public static function createFromArray($raw): self
|
||||||
|
{
|
||||||
|
return new self(
|
||||||
|
self::validateAliasAddress(trim($raw['alias_address'] ?? '')),
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
public function getAliasAddress(): string
|
||||||
|
{
|
||||||
|
return $this->aliasAddress;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
@ -64,6 +64,9 @@ class AccountController extends BaseController
|
||||||
return $this->showAccount404($response, $accountId);
|
return $this->showAccount404($response, $accountId);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// If the "add alias" form has been submitted, add the result message to the render data array
|
||||||
|
$renderData = $this->addLastActionResultToRenderData($renderData);
|
||||||
|
|
||||||
return $this->view->render($response, 'account_details.html.twig', $renderData);
|
return $this->view->render($response, 'account_details.html.twig', $renderData);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -210,4 +213,30 @@ class AccountController extends BaseController
|
||||||
// Redirect to edit form page via GET (PRG)
|
// Redirect to edit form page via GET (PRG)
|
||||||
return $response->withHeader('Location', $redirectTarget)->withStatus(303);
|
return $response->withHeader('Location', $redirectTarget)->withStatus(303);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
// -- /accounts/{id}/addalias - Create a new alias for the account
|
||||||
|
|
||||||
|
public function addAliasToAccount(Request $request, Response $response, array $args): Response
|
||||||
|
{
|
||||||
|
// Parse URL arguments and form data
|
||||||
|
$accountId = (int)$args['id'];
|
||||||
|
$addAliasData = $request->getParsedBody();
|
||||||
|
|
||||||
|
try {
|
||||||
|
// Validate input
|
||||||
|
$validatedAddAliasData = AccountAddAliasData::createFromArray($addAliasData);
|
||||||
|
$this->accountHandler->addAliasToAccount($accountId, $validatedAddAliasData);
|
||||||
|
|
||||||
|
// Save success result
|
||||||
|
$successMessage = "Alias <i>{$validatedAddAliasData->getAliasAddress()}</i> was added.";
|
||||||
|
$this->sessionHelper->setLastActionResult(ActionResult::createSuccessResult($successMessage));
|
||||||
|
} catch (InputValidationError $e) {
|
||||||
|
// Save error result
|
||||||
|
$this->sessionHelper->setLastActionResult(ActionResult::createErrorResult($e->getMessage(), $addAliasData));
|
||||||
|
}
|
||||||
|
|
||||||
|
// Redirect to edit form page via GET (PRG)
|
||||||
|
return $response->withHeader('Location', '/accounts/' . $accountId)->withStatus(303);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -265,4 +265,26 @@ class AccountHandler
|
||||||
'deleted_alias_count' => $deleteAliasCount,
|
'deleted_alias_count' => $deleteAliasCount,
|
||||||
];
|
];
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
// -- /accounts/{id}/addalias - Create a new alias for the account
|
||||||
|
|
||||||
|
public function addAliasToAccount(int $accountId, AccountAddAliasData $aliasAddData): void
|
||||||
|
{
|
||||||
|
// Check if account exists
|
||||||
|
try {
|
||||||
|
$this->accountRepository->fetchAccountById($accountId);
|
||||||
|
} catch (AccountNotFoundException $e) {
|
||||||
|
throw new InputValidationError('Account with ID ' . $accountId . ' does not exist!');
|
||||||
|
}
|
||||||
|
|
||||||
|
// Check if alias address is still available
|
||||||
|
$address = $aliasAddData->getAliasAddress();
|
||||||
|
if (!$this->accountRepository->checkUsernameAvailable($address) || !$this->aliasRepository->checkAliasAvailable($address)) {
|
||||||
|
throw new InputValidationError("Alias address \"$address\" is not available.");
|
||||||
|
}
|
||||||
|
|
||||||
|
// Create alias in database
|
||||||
|
$this->aliasRepository->createNewAlias($accountId, $address);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -33,5 +33,6 @@ class Routes
|
||||||
$app->post('/accounts/{id:[1-9][0-9]*}/edit', AccountController::class . ':editAccount');
|
$app->post('/accounts/{id:[1-9][0-9]*}/edit', AccountController::class . ':editAccount');
|
||||||
$app->get('/accounts/{id:[1-9][0-9]*}/delete', AccountController::class . ':showAccountDelete');
|
$app->get('/accounts/{id:[1-9][0-9]*}/delete', AccountController::class . ':showAccountDelete');
|
||||||
$app->post('/accounts/{id:[1-9][0-9]*}/delete', AccountController::class . ':deleteAccount');
|
$app->post('/accounts/{id:[1-9][0-9]*}/delete', AccountController::class . ':deleteAccount');
|
||||||
|
$app->post('/accounts/{id:[1-9][0-9]*}/addalias', AccountController::class . ':addAliasToAccount');
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -82,4 +82,20 @@
|
||||||
{% else %}
|
{% else %}
|
||||||
<p>No aliases.</p>
|
<p>No aliases.</p>
|
||||||
{% endif %}
|
{% endif %}
|
||||||
|
|
||||||
|
<form action="/accounts/{{ id }}/addalias" method="POST">
|
||||||
|
{{ include('includes/form_result_box.html.twig') }}
|
||||||
|
|
||||||
|
<table class="margin_vertical_1rem">
|
||||||
|
<tr>
|
||||||
|
<td><label for="add_alias_address">New alias:</label></td>
|
||||||
|
<td><input id="add_alias_address" name="alias_address" value="{{ formData['new_alias'] | default('') }}"/></td>
|
||||||
|
</tr>
|
||||||
|
<tr>
|
||||||
|
<td colspan="2">
|
||||||
|
<button type="submit">Add alias</button>
|
||||||
|
</td>
|
||||||
|
</tr>
|
||||||
|
</table>
|
||||||
|
</form>
|
||||||
{% endblock %}
|
{% endblock %}
|
||||||
|
|
|
||||||
Loading…
Reference in New Issue