register form fields
This commit is contained in:
@@ -22,6 +22,10 @@
|
|||||||
|
|
||||||
{% if error == "exists" %}
|
{% if error == "exists" %}
|
||||||
{{ ui::alert_danger(message=t(key="register-error-exists", lang=lang | default(value='sk')), extra="mt-3") }}
|
{{ ui::alert_danger(message=t(key="register-error-exists", lang=lang | default(value='sk')), extra="mt-3") }}
|
||||||
|
{% elif error == "mismatch" %}
|
||||||
|
{{ ui::alert_danger(message=t(key="set-password-mismatch", lang=lang | default(value='sk')), extra="mt-3") }}
|
||||||
|
{% elif error == "weak" %}
|
||||||
|
{{ ui::alert_danger(message=t(key="set-password-weak", lang=lang | default(value='sk')), extra="mt-3") }}
|
||||||
{% elif error %}
|
{% elif error %}
|
||||||
{{ ui::alert_danger(message=t(key="register-error-invalid", lang=lang | default(value='sk')), extra="mt-3") }}
|
{{ ui::alert_danger(message=t(key="register-error-invalid", lang=lang | default(value='sk')), extra="mt-3") }}
|
||||||
{% endif %}
|
{% endif %}
|
||||||
@@ -42,20 +46,12 @@
|
|||||||
<span class="text-xs text-on-surface/60 dark:text-on-surface-dark/60">{{ t(key="account-type-locked", lang=lang | default(value='sk')) }}</span>
|
<span class="text-xs text-on-surface/60 dark:text-on-surface-dark/60">{{ t(key="account-type-locked", lang=lang | default(value='sk')) }}</span>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<div class="flex flex-col gap-1">
|
|
||||||
<label for="name"
|
|
||||||
class="text-sm font-medium text-on-surface-strong dark:text-on-surface-dark-strong">
|
|
||||||
{{ t(key="register-name", lang=lang | default(value='sk')) }}
|
|
||||||
</label>
|
|
||||||
{{ ui::input(name="name", id="name", required=true, autocomplete="name", attrs="autofocus") }}
|
|
||||||
</div>
|
|
||||||
|
|
||||||
<div class="flex flex-col gap-1">
|
<div class="flex flex-col gap-1">
|
||||||
<label for="email"
|
<label for="email"
|
||||||
class="text-sm font-medium text-on-surface-strong dark:text-on-surface-dark-strong">
|
class="text-sm font-medium text-on-surface-strong dark:text-on-surface-dark-strong">
|
||||||
{{ t(key="login-email", lang=lang | default(value='sk')) }}
|
{{ t(key="login-email", lang=lang | default(value='sk')) }}
|
||||||
</label>
|
</label>
|
||||||
{{ ui::input(name="email", id="email", type="email", required=true, autocomplete="email") }}
|
{{ ui::input(name="email", id="email", type="email", required=true, autocomplete="email", attrs="autofocus") }}
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<div class="flex flex-col gap-1">
|
<div class="flex flex-col gap-1">
|
||||||
@@ -66,6 +62,14 @@
|
|||||||
{{ ui::input(name="password", id="password", type="password", required=true, autocomplete="new-password") }}
|
{{ ui::input(name="password", id="password", type="password", required=true, autocomplete="new-password") }}
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
|
<div class="flex flex-col gap-1">
|
||||||
|
<label for="password_confirm"
|
||||||
|
class="text-sm font-medium text-on-surface-strong dark:text-on-surface-dark-strong">
|
||||||
|
{{ t(key="set-password-confirm", lang=lang | default(value='sk')) }}
|
||||||
|
</label>
|
||||||
|
{{ ui::input(name="password_confirm", id="password_confirm", type="password", required=true, autocomplete="new-password") }}
|
||||||
|
</div>
|
||||||
|
|
||||||
{{ ui::button(label=t(key="register-submit", lang=lang | default(value='sk')), type="submit", extra="mt-1 w-full") }}
|
{{ ui::button(label=t(key="register-submit", lang=lang | default(value='sk')), type="submit", extra="mt-1 w-full") }}
|
||||||
</form>
|
</form>
|
||||||
|
|
||||||
|
|||||||
@@ -106,13 +106,50 @@ async fn register_page(
|
|||||||
register_view(&v, &jar, None)
|
register_view(&v, &jar, None)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// Registration form. The name is no longer collected from the user — it is
|
||||||
|
/// derived from the email — and the password is entered twice to guard against
|
||||||
|
/// typos.
|
||||||
|
#[derive(Debug, serde::Deserialize)]
|
||||||
|
struct RegisterForm {
|
||||||
|
email: String,
|
||||||
|
password: String,
|
||||||
|
password_confirm: String,
|
||||||
|
#[serde(default)]
|
||||||
|
account_type: Option<String>,
|
||||||
|
}
|
||||||
|
|
||||||
|
/// Derive a display name from an email address (its local part), falling back to
|
||||||
|
/// the full address when the local part is too short for the name validator.
|
||||||
|
fn name_from_email(email: &str) -> String {
|
||||||
|
let local = email.split('@').next().unwrap_or("").trim();
|
||||||
|
if local.chars().count() >= 2 {
|
||||||
|
local.to_string()
|
||||||
|
} else {
|
||||||
|
email.trim().to_string()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
#[debug_handler]
|
#[debug_handler]
|
||||||
async fn register(
|
async fn register(
|
||||||
jar: CookieJar,
|
jar: CookieJar,
|
||||||
ViewEngine(v): ViewEngine<TeraView>,
|
ViewEngine(v): ViewEngine<TeraView>,
|
||||||
State(ctx): State<AppContext>,
|
State(ctx): State<AppContext>,
|
||||||
Form(params): Form<RegisterParams>,
|
Form(form): Form<RegisterForm>,
|
||||||
) -> Result<Response> {
|
) -> Result<Response> {
|
||||||
|
if form.password != form.password_confirm {
|
||||||
|
return register_view(&v, &jar, Some("mismatch"));
|
||||||
|
}
|
||||||
|
if form.password.len() < 8 {
|
||||||
|
return register_view(&v, &jar, Some("weak"));
|
||||||
|
}
|
||||||
|
|
||||||
|
let params = RegisterParams {
|
||||||
|
name: name_from_email(&form.email),
|
||||||
|
email: form.email,
|
||||||
|
password: form.password,
|
||||||
|
account_type: form.account_type,
|
||||||
|
};
|
||||||
|
|
||||||
let user = match users::Model::create_with_password(&ctx.db, ¶ms).await {
|
let user = match users::Model::create_with_password(&ctx.db, ¶ms).await {
|
||||||
Ok(user) => user,
|
Ok(user) => user,
|
||||||
Err(ModelError::EntityAlreadyExists {}) => {
|
Err(ModelError::EntityAlreadyExists {}) => {
|
||||||
|
|||||||
Reference in New Issue
Block a user