(text "{% extends \"auth/base.html\" %} {% block head %}") (title (text "Register")) (text "{% endblock %} {% block title %}Register{% endblock %} {% block content %}") (script ("src" "https://challenges.cloudflare.com/turnstile/v0/api.js") ("defer" "")) (form ("class" "w-full flex flex-col gap-4") ("onsubmit" "register(event)") (div ("class" "flex flex-col gap-1") (label ("for" "username") (b (text "Username"))) (input ("type" "text") ("placeholder" "username") ("required" "") ("name" "username") ("id" "username"))) (div ("class" "flex flex-col gap-1") (label ("for" "password") (b (text "Password"))) (input ("type" "password") ("placeholder" "password") ("required" "") ("name" "password") ("id" "password"))) (text "{% if config.security.enable_invite_codes -%}") (div ("class" "flex flex-col gap-1") ("oninput" "check_should_show_purchase(event)") (label ("for" "invite_code") (b (text "Invite code (optional)"))) (input ("type" "text") ("placeholder" "invite code") ("name" "invite_code") ("id" "invite_code"))) (script (text "function check_should_show_purchase(e) { if (e.target.value.length > 0) { document.querySelector('[ui_ident=purchase_account]').classList.add('hidden'); document.querySelector('[ui_ident=create_account]').classList.remove('hidden'); globalThis.DO_PURCHASE = false; } else { document.querySelector('[ui_ident=purchase_account]').classList.remove('hidden'); document.querySelector('[ui_ident=create_account]').classList.add('hidden'); globalThis.DO_PURCHASE = true; } } globalThis.DO_PURCHASE = true;")) (text "{%- endif %}") (hr) (div ("class" "card-nest w-full") (div ("class" "card small flex items-center gap-2") (text "{{ icon \"scroll-text\" }}") (b (text "Policies"))) (div ("class" "card secondary flex flex-col gap-2") (span (text "By continuing, you agree to the following policies:")) (ul (li (a ("href" "{{ config.policies.terms_of_service }}") (text "Terms of service"))) (li (a ("href" "{{ config.policies.privacy }}") (text "Privacy policy")))) (div ("class" "flex items-center gap-2") (input ("type" "checkbox") ("name" "policy_consent") ("id" "policy_consent") ("class" "w-content") ("required" "")) (label ("for" "policy_consent") (text "I agree"))))) (div ("class" "cf-turnstile") ("data-sitekey" "{{ config.turnstile.site_key }}")) (hr) (text "{% if config.security.enable_invite_codes -%}") (div ("class" "w-full flex gap-2 justify-between") ("ui_ident" "purchase_account") (button (icon (text "credit-card")) (str (text "auth:action.purchase_account"))) (button ("class" "small square lowered") ("type" "button") ("onclick" "document.querySelector('[ui_ident=purchase_help]').classList.toggle('hidden')") (icon (text "circle-question-mark")))) (div ("class" "hidden lowered card w-full no_p_margin") ("ui_ident" "purchase_help") (b (text "What does \"Purchase account\" mean?")) (p (text "Your account will be created, but you cannot use it until you activate it for {{ config.stripe.supporter_price_text }}.")) (p (text "Alternatively, you can provide an invite code to create your account for free."))) (text "{%- endif %}") (button ("class" "{% if config.security.enable_invite_codes -%} hidden {%- endif %}") ("ui_ident" "create_account") (icon (text "plus")) (str (text "auth:action.create_account")))) (script (text "async function register(e) { e.preventDefault(); await trigger(\"atto::debounce\", [\"users::create\"]); fetch(\"/api/v1/auth/register\", { method: \"POST\", headers: { \"Content-Type\": \"application/json\", }, body: JSON.stringify({ username: e.target.username.value, password: e.target.password.value, policy_consent: e.target.policy_consent.checked, captcha_response: e.target.querySelector( \"[name=cf-turnstile-response]\", ).value, invite_code: (e.target.invite_code || { value: \"\" }).value, purchase: globalThis.DO_PURCHASE, }), }) .then((res) => res.json()) .then(async (res) => { trigger(\"atto::toast\", [ res.ok ? \"success\" : \"error\", res.message, ]); if (res.ok) { // update tokens const new_tokens = (await ns(\"me\")).LOGIN_ACCOUNT_TOKENS; new_tokens[e.target.username.value] = res.message; trigger(\"me::set_login_account_tokens\", [new_tokens]); // redirect setTimeout(() => { window.location.href = \"/\"; }, 150); } }); }")) (text "{% endblock %} {% block footer %}") (span ("class" "small w-full text-center") (text "Or, ") (a ("href" "/auth/login") (text "login"))) (text "{% endblock %}")