mirror of
https://github.com/element-hq/matrix-authentication-service.git
synced 2026-10-13 22:07:42 +00:00
The server-rendered registration form is replaced by a React island mounted on `/register`, which renders the CAPTCHA in-page, gives live password complexity feedback, and lays out the upstream provider buttons and the sign-in link the way `/login` does. The island owns the whole form, so every variant of the page is rendered from the mount data alone, and the user fills it in one step. Server-side validation errors are threaded back into it through the mount node, so a rejected submission re-renders with the errors attached to the fields they belong to. `RegisterContext` resolves the provider names and the sign-in link server-side so that the island only has to render them. The sign-in link is derived from the post-auth action in the query string instead of the `PostAuthContext` loaded from the database, which drops a round trip from both the GET and the invalid-form re-render. Registering now requires JavaScript, including on the variant with upstream providers only and on the one without a CAPTCHA: the <noscript> block shows a notice instead of a duplicate form, which could not work anyway when a CAPTCHA is configured. While the script loads, the page shows a skeleton of the form to avoid layout shifts, and a hidden error notice is revealed if it fails to boot. The server-rendered CAPTCHA component and its entrypoint are removed with their only consumer.
39 lines
1.4 KiB
HTML
39 lines
1.4 KiB
HTML
{#
|
|
Copyright 2025, 2026 Element Creations Ltd.
|
|
Copyright 2024, 2025 New Vector Ltd.
|
|
Copyright 2021-2024 The Matrix.org Foundation C.I.C.
|
|
|
|
SPDX-License-Identifier: AGPL-3.0-only OR LicenseRef-Element-Commercial
|
|
Please see LICENSE files in the repository root for full details.
|
|
-#}
|
|
|
|
{% set _ = translator(lang) %}
|
|
|
|
{% import "components/button.html" as button %}
|
|
{% import "components/field.html" as field %}
|
|
{% import "components/back_to_client.html" as back_to_client %}
|
|
{% import "components/logout.html" as logout %}
|
|
{% import "components/errors.html" as errors %}
|
|
{% import "components/icon.html" as icon %}
|
|
{% import "components/scope.html" as scope %}
|
|
|
|
<!DOCTYPE html>
|
|
<html lang="{{ lang }}">
|
|
<head>
|
|
<meta charset="utf-8">
|
|
<title>{% block title %}{{ _("app.name") }}{% endblock title %}</title>
|
|
<meta name="viewport" content="width=device-width, initial-scale=1">
|
|
{{ include_asset('src/entrypoints/vendor.css') | indent(4) | safe }}
|
|
{{ include_asset('src/entrypoints/shared.css') | indent(4) | safe }}
|
|
{{ include_asset('src/entrypoints/templates.css') | indent(4) | safe }}
|
|
{{ include_asset('src/entrypoints/templates.ts') | indent(4) | safe }}
|
|
{% block head %}{% endblock head %}
|
|
</head>
|
|
<body>
|
|
<div class="layout-container{% if consent_page is defined %} consent{% endif %}">
|
|
{% block content %}{% endblock content %}
|
|
{% include "components/footer.html" %}
|
|
</div>
|
|
</body>
|
|
</html>
|