diff options
| author | Adam Soltys <[email protected]> | 2024-12-31 15:21:10 -0800 |
|---|---|---|
| committer | Adam Soltys <[email protected]> | 2024-12-31 15:21:10 -0800 |
| commit | 62443cf59e0e5b3db94a1873b11eb815cd7829fa (patch) | |
| tree | 9cdcf40cb0672c138aba27e33e730d9fae7b4a3a /src | |
| parent | b5015d1161f9cd3e916182e737a1c67186b1cebc (diff) | |
| download | coinos-ui-62443cf59e0e5b3db94a1873b11eb815cd7829fa.tar.gz coinos-ui-62443cf59e0e5b3db94a1873b11eb815cd7829fa.zip | |
nostr sign in
Diffstat (limited to 'src')
| -rw-r--r-- | src/locales/en.json | 3 | ||||
| -rw-r--r-- | src/routes/(app)/[username]/(profile)/+layout.svelte | 4 | ||||
| -rw-r--r-- | src/routes/(app)/settings/+layout.svelte | 6 | ||||
| -rw-r--r-- | src/routes/(app)/settings/account/+page.svelte | 20 | ||||
| -rw-r--r-- | src/routes/(static)/login/+page.svelte | 4 | ||||
| -rw-r--r-- | src/routes/(static)/register/+page.server.ts | 9 | ||||
| -rw-r--r-- | src/routes/(static)/register/+page.svelte | 63 |
7 files changed, 81 insertions, 28 deletions
diff --git a/src/locales/en.json b/src/locales/en.json index a0d0f855..937b3be3 100644 --- a/src/locales/en.json +++ b/src/locales/en.json @@ -167,7 +167,8 @@ "createAccount": "Create account", "signIn": "Sign In", "signUp": "Sign Up", - "failed": "Login failed" + "failed": "Login failed", + "nostr": "Sign in with Nostr" }, "nav": { "dark": "Dark", diff --git a/src/routes/(app)/[username]/(profile)/+layout.svelte b/src/routes/(app)/[username]/(profile)/+layout.svelte index 6d8ddf94..a83ed8d0 100644 --- a/src/routes/(app)/[username]/(profile)/+layout.svelte +++ b/src/routes/(app)/[username]/(profile)/+layout.svelte @@ -128,7 +128,7 @@ <iconify-icon noobserver icon="ph:qr-code-bold" width="32"></iconify-icon> </button> - {#if subject.address || subject.about} + {#if subject.about} <div class="text-secondary mx-auto text-center lg:mx-0 break-words space-y-1" class:line-clamp-2={!showBio} @@ -136,7 +136,7 @@ onkeydown={toggleBio} > <div> - {subject.address || subject.about} + {subject.about} </div> {#if subject.website} diff --git a/src/routes/(app)/settings/+layout.svelte b/src/routes/(app)/settings/+layout.svelte index 14834669..cd25635d 100644 --- a/src/routes/(app)/settings/+layout.svelte +++ b/src/routes/(app)/settings/+layout.svelte @@ -42,7 +42,7 @@ { name: "security", key: "SECURITY" }, ]; - let { address, id, username } = $derived(user); + let { about, id, username } = $derived(user); let submitting = $state(); async function handleSubmit(e) { @@ -103,14 +103,14 @@ } } - if (["username", "address", "profile"].some((a) => user[a] !== prev[a])) { + if (["username", "about", "profile"].some((a) => user[a] !== prev[a])) { let event = { pubkey: user.pubkey, created_at: Math.floor(Date.now() / 1000), kind: 0, content: JSON.stringify({ name: user.username, - about: user.address, + about: user.about, picture: `${$page.url.origin}/public/${user.profile}.webp`, }), tags: [], diff --git a/src/routes/(app)/settings/account/+page.svelte b/src/routes/(app)/settings/account/+page.svelte index 7b222fe8..d4178fd1 100644 --- a/src/routes/(app)/settings/account/+page.svelte +++ b/src/routes/(app)/settings/account/+page.svelte @@ -7,7 +7,7 @@ let { data } = $props(); let { user } = $derived(data); let { id } = user; - let { address, banner, profile, display, email, username, verified } = + let { about, banner, picture, display, email, username, verified } = $state(user); let avatarFile, @@ -32,7 +32,7 @@ if (file.size > 10000000) return (tooLarge[type] = true); - if (type === "profile") { + if (type === "picture") { $avatar = { id, file, type, progress }; } else if (type === "banner") { $bannerStore = { id, file, type, progress }; @@ -40,7 +40,7 @@ var reader = new FileReader(); reader.onload = async (e) => { - if (type === "profile") { + if (type === "picture") { $avatar.src = e.target.result; } else if (type === "banner") { $bannerStore.src = e.target.result; @@ -99,14 +99,14 @@ <span class="font-bold">{$t("user.settings.profileImage")}</span> <div class="flex"> - {#if $avatar || profile} + {#if $avatar || picture} <div class="relative rounded-full overflow-hidden text-center w-20 h-20 my-auto hover:opacity-80 cursor-pointer" onclick={selectAvatar} onkeydown={selectAvatar} > <img - src={$avatar?.src || `/api/public/${profile}.webp`} + src={$avatar?.src || picture} class="absolute w-full h-full object-cover object-center visible overflow-hidden" alt={username} /> @@ -130,7 +130,7 @@ type="file" class="hidden" bind:this={avatarInput} - onchange={(e) => handleFile(e, "profile")} + onchange={(e) => handleFile(e, "picture")} /> </div> </div> @@ -147,7 +147,7 @@ {#if $bannerStore || banner} <img - src={$bannerStore ? $bannerStore.src : `/api/public/${banner}.webp`} + src={$bannerStore ? $bannerStore.src : banner} class="w-full object-cover object-center visible overflow-hidden h-48 mb-4 hover:opacity-80" onclick={selectBanner} onkeydown={selectBanner} @@ -181,13 +181,13 @@ </div> <div> - <label for="address" class="font-bold mb-1 block" + <label for="about" class="font-bold mb-1 block" >{$t("user.settings.about")}</label > <textarea type="text" - name="address" - bind:value={address} + name="about" + bind:value={about} placeholder={$t("user.settings.aboutPlaceholder")} ></textarea> </div> diff --git a/src/routes/(static)/login/+page.svelte b/src/routes/(static)/login/+page.svelte index e64434fb..bfd30fe2 100644 --- a/src/routes/(static)/login/+page.svelte +++ b/src/routes/(static)/login/+page.svelte @@ -159,14 +159,14 @@ > </div> - <button type="submit" class="btn" bind:this={btn}> + <button type="submit" class="btn btn-accent" bind:this={btn}> {$t("login.signIn")} </button> {#if nostr} <button type="button" class="btn" onclick={nostrLogin}> <img src="/images/nostr.png" class="w-8" /> - <div class="my-auto">{$t("user.settings.nostr")}</div> + <div class="my-auto">{$t("login.nostr")}</div> </button> {/if} diff --git a/src/routes/(static)/register/+page.server.ts b/src/routes/(static)/register/+page.server.ts index 4cff0ed9..b459c622 100644 --- a/src/routes/(static)/register/+page.server.ts +++ b/src/routes/(static)/register/+page.server.ts @@ -1,4 +1,4 @@ -import { fd, login, post } from "$lib/utils"; +import { get, fd, login, post } from "$lib/utils"; import { fail, redirect } from "@sveltejs/kit"; export const load = async ({ parent }) => { @@ -6,8 +6,9 @@ export const load = async ({ parent }) => { if (user) redirect(307, `/${user.username}`); const index = Math.floor(Math.random() * 64) + 1; + const { id } = await get("/challenge"); - return { index }; + return { index, id }; }; export const actions = { @@ -23,17 +24,13 @@ export const actions = { if (loginRedirect === "undefined") loginRedirect = undefined; try { - console.log("ST", Date.now()); await post("/register", { user }, { "cf-connecting-ip": ip }); - console.log("END", Date.now()); } catch (e) { ({ message: error } = e as Error); } try { - console.log("ST", Date.now()); await login(user, cookies, ip); - console.log("END", Date.now()); error = null; } catch (e) { const { message } = e as Error; diff --git a/src/routes/(static)/register/+page.svelte b/src/routes/(static)/register/+page.svelte index 4a4a3c57..8738e32b 100644 --- a/src/routes/(static)/register/+page.svelte +++ b/src/routes/(static)/register/+page.svelte @@ -1,4 +1,6 @@ <script> + import { browser } from "$app/environment"; + import { onMount } from "svelte"; import punks from "$lib/punks"; import { upload } from "$lib/upload"; import { afterNavigate, invalidateAll } from "$app/navigation"; @@ -24,6 +26,12 @@ } from "unique-names-generator"; let { form = $bindable(), data } = $props(); + let nostr = $state(); + let { id } = $derived(data); + + onMount(() => { + if (browser && window.nostr) nostr = true; + }); let username = $state(); let { index } = $state(data); @@ -153,6 +161,43 @@ $effect(() => { token && token?.length === 6 && tick().then(() => btn.click()); }); + + let nostrLogin = async () => { + let pubkey = await window.nostr.getPublicKey(); + const formData = new FormData(); + + let ev = { + kind: 1, + pubkey, + created_at: Date.now(), + content: id, + tags: [], + }; + + try { + let signedEvent = await window.nostr.signEvent(ev); + + formData.append("loginRedirect", redirect); + formData.append("token", token); + formData.append("event", JSON.stringify(signedEvent)); + formData.append("id", id); + + let response = await fetch("/login?/nostr", { + method: "POST", + body: formData, + }); + + const result = deserialize(await response.text()); + + if (result.type === "success") { + await invalidateAll(); + } + + applyAction(result); + } catch (e) { + fail(e.message); + } + }; </script> {#if need2fa} @@ -176,7 +221,8 @@ onclick={decr} aria-label="Previous" > - <iconify-icon noobserver icon="ph:caret-left-bold" width="32"></iconify-icon> + <iconify-icon noobserver icon="ph:caret-left-bold" width="32" + ></iconify-icon> </button> <button class="block relative w-32 mx-auto" onclick={selectAvatar}> <div @@ -191,7 +237,8 @@ <div class="absolute bg-base-100 rounded-full p-2 mx-auto right-0 bottom-0 z-10 w-12" > - <iconify-icon noobserver icon="ph:upload-simple-bold" width="24"></iconify-icon> + <iconify-icon noobserver icon="ph:upload-simple-bold" width="24" + ></iconify-icon> </div> </button> <button @@ -199,7 +246,8 @@ onclick={incr} aria-label="Next" > - <iconify-icon noobserver icon="ph:caret-right-bold" width="32"></iconify-icon> + <iconify-icon noobserver icon="ph:caret-right-bold" width="32" + ></iconify-icon> </button> </div> @@ -250,7 +298,7 @@ bind:show={revealPassword} /> - <button type="submit" class="btn" disabled={loading} bind:this={btn}> + <button type="submit" class="btn btn-accent" disabled={loading} bind:this={btn}> {#if loading} <Spinner /> {:else} @@ -258,6 +306,13 @@ {/if} </button> + {#if nostr} + <button type="button" class="btn" onclick={nostrLogin}> + <img src="/images/nostr.png" class="w-8" /> + <div class="my-auto">{$t("login.nostr")}</div> + </button> + {/if} + <p class="text-secondary text-center font-medium"> {$t("login.haveAccount")} <a |
