feat: show deSEC password field only after email-already-registered failure, via POST /containers and Twig (no sessions, no query params)

Agent-Logs-Url: https://github.com/nextcloud/all-in-one/sessions/9eadc186-a642-409b-871d-f2bbb47f20ce

Co-authored-by: szaimen <42591237+szaimen@users.noreply.github.com>
This commit is contained in:
copilot-swe-agent[bot]
2026-04-26 16:36:06 +00:00
committed by GitHub
parent 2b78dcc9cc
commit 44b257a2b5
4 changed files with 69 additions and 12 deletions

View File

@@ -112,7 +112,13 @@ $app->post('/api/configuration', \AIO\Controller\ConfigurationController::class
$app->post('/api/desec/register', \AIO\Controller\DesecController::class . ':Register');
// Views
$app->get('/containers', function (Request $request, Response $response, array $args) use ($container) {
// Shared closure that renders the containers page.
// $desecVars can override 'desec_show_password', 'desec_prefill_email', and 'desec_error'.
$renderContainersPage = function (
Response $response,
Request $request,
array $desecVars = [],
) use ($container): Response {
$view = Twig::fromRequest($request);
$view->addExtension(new \AIO\Twig\ClassExtension());
/** @var \AIO\Data\ConfigurationManager $configurationManager */
@@ -130,7 +136,7 @@ $app->get('/containers', function (Request $request, Response $response, array $
$bypass_container_update = isset($params['bypass_container_update']);
$skip_domain_validation = isset($params['skip_domain_validation']);
return $view->render($response, 'containers.twig', [
return $view->render($response, 'containers.twig', array_merge([
'domain' => $configurationManager->domain,
'apache_port' => $configurationManager->apachePort,
'borg_backup_host_location' => $configurationManager->borgBackupHostLocation,
@@ -185,8 +191,39 @@ $app->get('/containers', function (Request $request, Response $response, array $
'desec_password' => $configurationManager->desecPassword,
'is_desec_domain' => $configurationManager->isDesecDomain(),
'desec_account_registered' => $configurationManager->isDesecAccountRegistered(),
]);
'desec_show_password' => false,
'desec_prefill_email' => '',
'desec_error' => '',
], $desecVars));
};
$app->get('/containers', function (Request $request, Response $response, array $args) use ($renderContainersPage): Response {
return $renderContainersPage($response, $request);
})->setName('profile');
$app->post('/containers', function (Request $request, Response $response, array $args) use ($container, $renderContainersPage): Response {
$email = (string)($request->getParsedBody()['desec_email'] ?? '');
$slug = (string)($request->getParsedBody()['desec_slug'] ?? '');
$password = (string)($request->getParsedBody()['desec_password'] ?? '');
/** @var \AIO\Desec\DesecManager $desecManager */
$desecManager = $container->get(\AIO\Desec\DesecManager::class);
try {
$desecManager->register($email, $slug, $password);
return $response->withStatus(303)->withHeader('Location', '/containers');
} catch (\AIO\Desec\AlreadyRegisteredException $ex) {
return $renderContainersPage($response, $request, [
'desec_show_password' => true,
'desec_prefill_email' => $email,
'desec_error' => $ex->getMessage(),
]);
} catch (\Exception $ex) {
return $renderContainersPage($response, $request, [
'desec_prefill_email' => $email,
'desec_error' => $ex->getMessage(),
]);
}
});
$app->get('/login', function (Request $request, Response $response, array $args) use ($container) {
$view = Twig::fromRequest($request);
/** @var \AIO\Docker\DockerActionManager $dockerActionManager */

View File

@@ -0,0 +1,17 @@
<?php
declare(strict_types=1);
namespace AIO\Desec;
/**
* Thrown when the deSEC API reports that the supplied email address is already
* associated with an existing account (HTTP 400 with an "email" error field).
*/
class AlreadyRegisteredException extends \Exception {
public function __construct(string $email) {
parent::__construct(
'This email address is already registered at deSEC. '
. 'If this is your account, please enter your deSEC password in the password field and try again.',
);
}
}

View File

@@ -122,10 +122,7 @@ class DesecManager {
if ($code === 400) {
$data = json_decode($body, true, 512, JSON_THROW_ON_ERROR);
if (is_array($data) && isset($data['email'])) {
throw new \Exception(
'This email address is already registered at deSEC. '
. 'If this is your account, please enter your deSEC password in the password field and try again.',
);
throw new AlreadyRegisteredException($email);
}
throw new \Exception('Registration at deSEC failed (HTTP 400): ' . $body);
}

View File

@@ -4,7 +4,8 @@
{% if desec_account_registered %}
<p>Your deSEC account (<strong>{{ desec_email }}</strong>) was registered successfully but the domain could not be registered. Please enter a desired subdomain slug (the part before <code>.dedyn.io</code>) and try again, or leave it blank for a random one.</p>
<p>Your deSEC login credentials (for <a target="_blank" href="https://desec.io">desec.io</a>): Email: <strong>{{ desec_email }}</strong>. <details style="display:inline"><summary>Reveal deSEC password</summary><strong>{{ desec_password }}</strong></details>. Please save these in a safe place.</p>
<form method="POST" action="api/desec/register" class="xhr">
{% if desec_error %}<p class="error">{{ desec_error }}</p>{% endif %}
<form method="POST" action="/containers">
<input type="hidden" name="{{csrf.keys.name}}" value="{{csrf.name}}">
<input type="hidden" name="{{csrf.keys.value}}" value="{{csrf.value}}">
<input type="text" name="desec_slug" placeholder="my-nextcloud (optional)" pattern="[a-z0-9]([a-z0-9\-]{0,61}[a-z0-9])?" title="Only lowercase letters, digits and hyphens (163 characters). No leading or trailing hyphen." />
@@ -12,12 +13,17 @@
</form>
{% else %}
<p>Please enter your email address. You can also enter a desired subdomain slug (the part before <code>.dedyn.io</code>); leave it blank for a random one.</p>
<p>If you already have a deSEC account for this email address, enter your deSEC password in the optional password field below to log in with it instead of creating a new account.</p>
<form method="POST" action="api/desec/register" class="xhr">
{% if desec_show_password %}
<p>If you already have a deSEC account for this email address, enter your deSEC password in the optional password field below to log in with it instead of creating a new account.</p>
{% endif %}
{% if desec_error %}<p class="error">{{ desec_error }}</p>{% endif %}
<form method="POST" action="/containers">
<input type="hidden" name="{{csrf.keys.name}}" value="{{csrf.name}}">
<input type="hidden" name="{{csrf.keys.value}}" value="{{csrf.value}}">
<input type="email" name="desec_email" placeholder="your@email.com" required />
<input type="password" name="desec_password" placeholder="deSEC password (only if already registered)" autocomplete="current-password" />
<input type="email" name="desec_email" placeholder="your@email.com" value="{{ desec_prefill_email }}" required />
{% if desec_show_password %}
<input type="password" name="desec_password" placeholder="deSEC password" autocomplete="current-password" />
{% endif %}
<input type="text" name="desec_slug" placeholder="my-nextcloud (optional)" pattern="[a-z0-9]([a-z0-9\-]{0,61}[a-z0-9])?" title="Only lowercase letters, digits and hyphens (163 characters). No leading or trailing hyphen." />
<input type="submit" value="Register free domain via deSEC" />
</form>