diff options
Diffstat (limited to 'kittybox-rs/src/frontend')
-rw-r--r-- | kittybox-rs/src/frontend/indieauth.js | 107 | ||||
-rw-r--r-- | kittybox-rs/src/frontend/mod.rs | 4 | ||||
-rw-r--r-- | kittybox-rs/src/frontend/onboarding.js | 87 |
3 files changed, 2 insertions, 196 deletions
diff --git a/kittybox-rs/src/frontend/indieauth.js b/kittybox-rs/src/frontend/indieauth.js deleted file mode 100644 index 1762bdd..0000000 --- a/kittybox-rs/src/frontend/indieauth.js +++ /dev/null @@ -1,107 +0,0 @@ -const WEBAUTHN_TIMEOUT = 60 * 1000; - -async function webauthn_create_credential() { - const response = await fetch("/.kittybox/webauthn/pre_register"); - const { challenge, rp, user } = await response.json(); - - return await navigator.credentials.create({ - publicKey: { - challenge: Uint8Array.from(challenge, c => c.charCodeAt(0)), - rp: rp, - user: { - id: Uint8Array.from(user.cred_id), - name: user.name, - displayName: user.displayName - }, - pubKeyCredParams: [{alg: -7, type: "public-key"}], - authenticatorSelection: {}, - timeout: WEBAUTHN_TIMEOUT, - attestation: "none" - } - }); -} - -async function webauthn_authenticate() { - const response = await fetch("/.kittybox/webauthn/pre_auth"); - const { challenge, credentials } = await response.json(); - - try { - return await navigator.credentials.get({ - publicKey: { - challenge: Uint8Array.from(challenge, c => c.charCodeAt(0)), - allowCredentials: credentials.map(cred => ({ - id: Uint8Array.from(cred.id, c => c.charCodeAt(0)), - type: cred.type - })), - timeout: WEBAUTHN_TIMEOUT - } - }) - } catch (e) { - console.error("WebAuthn authentication failed:", e); - alert("Using your authenticator failed. (Check the DevTools for details)"); - throw e; - } -} - -async function submit_handler(e) { - e.preventDefault(); - const form = e.target; - - let scopes = form.elements.scope === undefined ? [] : Array.from(form.elements.scope) - .filter(e => e.checked) - .map(e => e.value); - - const authorization_request = { - response_type: form.elements.response_type.value, - client_id: form.elements.client_id.value, - redirect_uri: form.elements.redirect_uri.value, - state: form.elements.state.value, - code_challenge: form.elements.code_challenge.value, - code_challenge_method: form.elements.code_challenge_method.value, - // I would love to leave that as a list, but such is the form of - // IndieAuth. application/x-www-form-urlencoded doesn't have - // lists, so scopes are space-separated instead. It is annoying. - scope: scopes.length > 0 ? scopes.join(" ") : undefined, - }; - - let credential = null; - switch (form.elements.auth_method.value) { - case "password": - credential = form.elements.user_password.value; - if (credential.length == 0) { - alert("Please enter a password.") - return - } - break; - case "webauthn": - credential = await webauthn_authenticate(); - break; - default: - alert("Please choose an authentication method.") - return; - } - - console.log("Authorization request:", authorization_request); - console.log("Authentication method:", credential); - - const body = JSON.stringify({ - request: authorization_request, - authorization_method: credential - }); - console.log(body); - - const response = await fetch(form.action, { - method: form.method, - body: body, - headers: { - "Content-Type": "application/json" - } - }); - - if (response.ok) { - window.location.href = response.headers.get("Location") - } -} - -document.getElementById("indieauth_page") - .addEventListener("submit", submit_handler); diff --git a/kittybox-rs/src/frontend/mod.rs b/kittybox-rs/src/frontend/mod.rs index e2187c9..43a2824 100644 --- a/kittybox-rs/src/frontend/mod.rs +++ b/kittybox-rs/src/frontend/mod.rs @@ -268,9 +268,9 @@ pub async fn catchall<D: Storage>( } const STYLE_CSS: &[u8] = include_bytes!("./style.css"); -const ONBOARDING_JS: &[u8] = include_bytes!("./onboarding.js"); +const ONBOARDING_JS: &[u8] = include_bytes!(concat!(env!("OUT_DIR"), "/onboarding.js")); const ONBOARDING_CSS: &[u8] = include_bytes!("./onboarding.css"); -const INDIEAUTH_JS: &[u8] = include_bytes!("./indieauth.js"); +const INDIEAUTH_JS: &[u8] = include_bytes!(concat!(env!("OUT_DIR"), "/indieauth.js")); const MIME_JS: &str = "application/javascript"; const MIME_CSS: &str = "text/css"; diff --git a/kittybox-rs/src/frontend/onboarding.js b/kittybox-rs/src/frontend/onboarding.js deleted file mode 100644 index c5a1481..0000000 --- a/kittybox-rs/src/frontend/onboarding.js +++ /dev/null @@ -1,87 +0,0 @@ -const firstOnboardingCard = "intro"; - -function switchOnboardingCard(card) { - Array.from(document.querySelectorAll("form.onboarding > fieldset")).map(node => { - if (node.id == card) { - node.style.display = "block"; - } else { - node.style.display = "none"; - } - }); - - Array.from(document.querySelectorAll("form.onboarding > ul#progressbar > li")).map(node => { - if (node.id == card) { - node.classList.add("active") - } else { - node.classList.remove("active") - } - }) -}; - -window.kittybox_onboarding = { - switchOnboardingCard -}; - -document.querySelector("form.onboarding > ul#progressbar").style.display = ""; -switchOnboardingCard(firstOnboardingCard); - -function switchCardOnClick(event) { - switchOnboardingCard(event.target.dataset.card) -} - -function multiInputAddMore(event) { - let parent = event.target.parentElement; - let template = event.target.parentElement.querySelector("template").content.cloneNode(true); - parent.prepend(template); -} - -Array.from(document.querySelectorAll("form.onboarding > fieldset button.switch_card")).map(button => { - button.addEventListener("click", switchCardOnClick) -}) - -Array.from(document.querySelectorAll("form.onboarding > fieldset div.multi_input > button.add_more")).map(button => { - button.addEventListener("click", multiInputAddMore) - multiInputAddMore({ target: button }); -}) - -const form = document.querySelector("form.onboarding"); -console.log(form); -form.onsubmit = async (event) => { - console.log(event); - event.preventDefault(); - const form = event.target; - const json = { - user: { - type: ["h-card"], - properties: { - name: [form.querySelector("#hcard_name").value], - pronoun: Array.from(form.querySelectorAll("#hcard_pronouns")).map(input => input.value).filter(i => i != ""), - url: Array.from(form.querySelectorAll("#hcard_url")).map(input => input.value).filter(i => i != ""), - note: [form.querySelector("#hcard_note").value] - } - }, - first_post: { - type: ["h-entry"], - properties: { - content: [form.querySelector("#first_post_content").value] - } - }, - blog_name: form.querySelector("#blog_name").value, - feeds: Array.from(form.querySelectorAll(".multi_input#custom_feeds > fieldset.feed")).map(form => { - return { - name: form.querySelector("#feed_name").value, - slug: form.querySelector("#feed_slug").value - } - }).filter(feed => feed.name == "" || feed.slug == "") - }; - - await fetch("/.kittybox/onboarding", { - method: "POST", - body: JSON.stringify(json), - headers: { "Content-Type": "application/json" } - }).then(response => { - if (response.status == 201) { - window.location.href = window.location.href; - } - }) -} |