mirror of
https://github.com/coracle-social/flotilla.git
synced 2025-12-11 11:27:03 +00:00
Refactor login, pass bunker to alerts
This commit is contained in:
@@ -466,27 +466,34 @@ export type AlertParams = {
|
|||||||
email: string
|
email: string
|
||||||
relay: string
|
relay: string
|
||||||
filters: Filter[]
|
filters: Filter[]
|
||||||
|
bunker: string
|
||||||
|
secret: string
|
||||||
}
|
}
|
||||||
|
|
||||||
export const makeAlert = async ({cron, email, relay, filters}: AlertParams) => {
|
export const makeAlert = async ({cron, email, relay, filters, bunker, secret}: AlertParams) => {
|
||||||
const handler =
|
const tags = [
|
||||||
"31990:97c70a44366a6535c145b333f973ea86dfdc2d7a99da618c40c64705ad98e322:1737058597050"
|
|
||||||
const handlerRelay = "wss://relay.nostr.band/"
|
|
||||||
|
|
||||||
return createEvent(ALERT, {
|
|
||||||
content: await signer
|
|
||||||
.get()
|
|
||||||
.nip44.encrypt(
|
|
||||||
NOTIFIER_PUBKEY,
|
|
||||||
JSON.stringify([
|
|
||||||
["cron", cron],
|
["cron", cron],
|
||||||
["email", email],
|
["email", email],
|
||||||
["relay", relay],
|
["relay", relay],
|
||||||
["channel", "email"],
|
["channel", "email"],
|
||||||
["handler", handler, handlerRelay, "web"],
|
[
|
||||||
...unionFilters(filters).map(filter => ["filter", JSON.stringify(filter)]),
|
"handler",
|
||||||
]),
|
"31990:97c70a44366a6535c145b333f973ea86dfdc2d7a99da618c40c64705ad98e322:1737058597050",
|
||||||
),
|
"wss://relay.nostr.band/",
|
||||||
|
"web",
|
||||||
|
],
|
||||||
|
]
|
||||||
|
|
||||||
|
for (const filter of unionFilters(filters)) {
|
||||||
|
tags.push(["filter", JSON.stringify(filter)])
|
||||||
|
}
|
||||||
|
|
||||||
|
if (bunker) {
|
||||||
|
tags.push(["nip46", secret, bunker])
|
||||||
|
}
|
||||||
|
|
||||||
|
return createEvent(ALERT, {
|
||||||
|
content: await signer.get().nip44.encrypt(NOTIFIER_PUBKEY, JSON.stringify(tags)),
|
||||||
tags: [
|
tags: [
|
||||||
["d", randomId()],
|
["d", randomId()],
|
||||||
["p", NOTIFIER_PUBKEY],
|
["p", NOTIFIER_PUBKEY],
|
||||||
|
|||||||
@@ -3,6 +3,7 @@
|
|||||||
import {randomInt} from "@welshman/lib"
|
import {randomInt} from "@welshman/lib"
|
||||||
import {displayRelayUrl, THREAD, MESSAGE, EVENT_TIME, COMMENT} from "@welshman/util"
|
import {displayRelayUrl, THREAD, MESSAGE, EVENT_TIME, COMMENT} from "@welshman/util"
|
||||||
import type {Filter} from "@welshman/util"
|
import type {Filter} from "@welshman/util"
|
||||||
|
import type {Nip46ResponseWithResult} from "@welshman/signer"
|
||||||
import {pubkey} from "@welshman/app"
|
import {pubkey} from "@welshman/app"
|
||||||
import Icon from "@lib/components/Icon.svelte"
|
import Icon from "@lib/components/Icon.svelte"
|
||||||
import Button from "@lib/components/Button.svelte"
|
import Button from "@lib/components/Button.svelte"
|
||||||
@@ -10,11 +11,13 @@
|
|||||||
import Spinner from "@lib/components/Spinner.svelte"
|
import Spinner from "@lib/components/Spinner.svelte"
|
||||||
import ModalHeader from "@lib/components/ModalHeader.svelte"
|
import ModalHeader from "@lib/components/ModalHeader.svelte"
|
||||||
import ModalFooter from "@lib/components/ModalFooter.svelte"
|
import ModalFooter from "@lib/components/ModalFooter.svelte"
|
||||||
|
import InfoBunker from "@app/components/InfoBunker.svelte"
|
||||||
|
import BunkerConnect, {BunkerConnectController} from "@app/components/BunkerConnect.svelte"
|
||||||
import {GENERAL, getMembershipUrls, getMembershipRoomsByUrl, userMembership} from "@app/state"
|
import {GENERAL, getMembershipUrls, getMembershipRoomsByUrl, userMembership} from "@app/state"
|
||||||
import {loadAlertStatuses} from "@app/requests"
|
import {loadAlertStatuses} from "@app/requests"
|
||||||
import {publishAlert} from "@app/commands"
|
import {publishAlert} from "@app/commands"
|
||||||
import {pushToast} from "@app/toast"
|
import {pushToast} from "@app/toast"
|
||||||
|
import {pushModal} from "@app/modal"
|
||||||
const timezone = new Date()
|
const timezone = new Date()
|
||||||
.toString()
|
.toString()
|
||||||
.match(/GMT[^\s]+/)![0]
|
.match(/GMT[^\s]+/)![0]
|
||||||
@@ -29,12 +32,36 @@
|
|||||||
let cron = WEEKLY
|
let cron = WEEKLY
|
||||||
let email = ""
|
let email = ""
|
||||||
let relay = ""
|
let relay = ""
|
||||||
|
let bunker = ""
|
||||||
|
let secret = ""
|
||||||
let notifyThreads = true
|
let notifyThreads = true
|
||||||
let notifyCalendar = true
|
let notifyCalendar = true
|
||||||
let notifyChat = false
|
let notifyChat = false
|
||||||
|
let showBunker = false
|
||||||
|
|
||||||
const back = () => history.back()
|
const back = () => history.back()
|
||||||
|
|
||||||
|
const controller = new BunkerConnectController({
|
||||||
|
onNostrConnect: (response: Nip46ResponseWithResult) => {
|
||||||
|
bunker = controller.broker.getBunkerUrl()
|
||||||
|
secret = controller.broker.params.clientSecret
|
||||||
|
showBunker = false
|
||||||
|
},
|
||||||
|
})
|
||||||
|
|
||||||
|
const connectBunker = () => {
|
||||||
|
showBunker = true
|
||||||
|
}
|
||||||
|
|
||||||
|
const hideBunker = () => {
|
||||||
|
showBunker = false
|
||||||
|
}
|
||||||
|
|
||||||
|
const clearBunker = () => {
|
||||||
|
bunker = ""
|
||||||
|
secret = ""
|
||||||
|
}
|
||||||
|
|
||||||
const submit = async () => {
|
const submit = async () => {
|
||||||
if (!email.includes("@")) {
|
if (!email.includes("@")) {
|
||||||
return pushToast({
|
return pushToast({
|
||||||
@@ -79,7 +106,7 @@
|
|||||||
loading = true
|
loading = true
|
||||||
|
|
||||||
try {
|
try {
|
||||||
const thunk = await publishAlert({cron, email, relay, filters})
|
const thunk = await publishAlert({cron, email, relay, filters, bunker, secret})
|
||||||
|
|
||||||
await thunk.result
|
await thunk.result
|
||||||
await loadAlertStatuses($pubkey!)
|
await loadAlertStatuses($pubkey!)
|
||||||
@@ -98,6 +125,13 @@
|
|||||||
Add an Alert
|
Add an Alert
|
||||||
{/snippet}
|
{/snippet}
|
||||||
</ModalHeader>
|
</ModalHeader>
|
||||||
|
{#if showBunker}
|
||||||
|
<div class="card2 flex flex-col items-center gap-4 bg-base-300">
|
||||||
|
<p>Scan using a nostr signer, or click to copy.</p>
|
||||||
|
<BunkerConnect {controller} />
|
||||||
|
<Button class="btn btn-neutral btn-sm" onclick={hideBunker}>Cancel</Button>
|
||||||
|
</div>
|
||||||
|
{:else}
|
||||||
<FieldInline>
|
<FieldInline>
|
||||||
{#snippet label()}
|
{#snippet label()}
|
||||||
<p>Email Address*</p>
|
<p>Email Address*</p>
|
||||||
@@ -153,12 +187,38 @@
|
|||||||
</div>
|
</div>
|
||||||
{/snippet}
|
{/snippet}
|
||||||
</FieldInline>
|
</FieldInline>
|
||||||
|
<div class="card2 flex flex-col gap-3 bg-base-300">
|
||||||
|
<div class="flex items-center justify-between">
|
||||||
|
<strong>Connect a Bunker</strong>
|
||||||
|
<span class="flex items-center gap-2 text-sm" class:text-primary={bunker}>
|
||||||
|
{#if bunker}
|
||||||
|
<Icon icon="check-circle" size={5} />
|
||||||
|
Connected
|
||||||
|
{:else}
|
||||||
|
<Icon icon="close-circle" size={5} />
|
||||||
|
Not Connected
|
||||||
|
{/if}
|
||||||
|
</span>
|
||||||
|
</div>
|
||||||
|
<p class="text-sm">
|
||||||
|
Required for receiving alerts about spaces with access controls. You can get one from your
|
||||||
|
<Button class="text-primary" onclick={() => pushModal(InfoBunker)}>remote signer app</Button
|
||||||
|
>.
|
||||||
|
</p>
|
||||||
|
{#if bunker}
|
||||||
|
<Button class="btn btn-neutral btn-sm flex-grow" onclick={clearBunker}>Disconnect</Button>
|
||||||
|
{:else}
|
||||||
|
<Button class="btn btn-primary btn-sm w-full flex-grow" onclick={connectBunker}
|
||||||
|
>Connect</Button>
|
||||||
|
{/if}
|
||||||
|
</div>
|
||||||
|
{/if}
|
||||||
<ModalFooter>
|
<ModalFooter>
|
||||||
<Button class="btn btn-link" onclick={back}>
|
<Button class="btn btn-link" onclick={back}>
|
||||||
<Icon icon="alt-arrow-left" />
|
<Icon icon="alt-arrow-left" />
|
||||||
Go back
|
Go back
|
||||||
</Button>
|
</Button>
|
||||||
<Button type="submit" class="btn btn-primary" disabled={loading}>
|
<Button type="submit" class="btn btn-primary" disabled={loading || showBunker}>
|
||||||
<Spinner {loading}>Confirm</Spinner>
|
<Spinner {loading}>Confirm</Spinner>
|
||||||
<Icon icon="alt-arrow-right" />
|
<Icon icon="alt-arrow-right" />
|
||||||
</Button>
|
</Button>
|
||||||
|
|||||||
@@ -1,12 +1,20 @@
|
|||||||
<script lang="ts">
|
<script lang="ts">
|
||||||
|
import {onMount} from "svelte"
|
||||||
|
import {pubkey} from "@welshman/app"
|
||||||
import Icon from "@lib/components/Icon.svelte"
|
import Icon from "@lib/components/Icon.svelte"
|
||||||
import Button from "@lib/components/Button.svelte"
|
import Button from "@lib/components/Button.svelte"
|
||||||
import AlertAdd from "@app/components/AlertAdd.svelte"
|
import AlertAdd from "@app/components/AlertAdd.svelte"
|
||||||
import AlertItem from "@app/components/AlertItem.svelte"
|
import AlertItem from "@app/components/AlertItem.svelte"
|
||||||
|
import {loadAlertStatuses, loadAlerts} from "@app/requests"
|
||||||
import {pushModal} from "@app/modal"
|
import {pushModal} from "@app/modal"
|
||||||
import {alerts} from "@app/state"
|
import {alerts} from "@app/state"
|
||||||
|
|
||||||
const startAlert = () => pushModal(AlertAdd)
|
const startAlert = () => pushModal(AlertAdd)
|
||||||
|
|
||||||
|
onMount(() => {
|
||||||
|
loadAlertStatuses($pubkey!)
|
||||||
|
loadAlerts($pubkey!)
|
||||||
|
})
|
||||||
</script>
|
</script>
|
||||||
|
|
||||||
<div class="card2 bg-alt flex flex-col gap-6 shadow-xl">
|
<div class="card2 bg-alt flex flex-col gap-6 shadow-xl">
|
||||||
|
|||||||
78
src/app/components/BunkerConnect.svelte
Normal file
78
src/app/components/BunkerConnect.svelte
Normal file
@@ -0,0 +1,78 @@
|
|||||||
|
<script module lang="ts">
|
||||||
|
import type {Nip46ResponseWithResult} from "@welshman/signer"
|
||||||
|
import {Nip46Broker, makeSecret} from "@welshman/signer"
|
||||||
|
import {NIP46_PERMS, PLATFORM_URL, PLATFORM_NAME, PLATFORM_LOGO, SIGNER_RELAYS} from "@app/state"
|
||||||
|
|
||||||
|
export class BunkerConnectController {
|
||||||
|
url = $state("")
|
||||||
|
bunker = $state("")
|
||||||
|
loading = $state(false)
|
||||||
|
clientSecret = makeSecret()
|
||||||
|
abortController = new AbortController()
|
||||||
|
broker = Nip46Broker.get({clientSecret: this.clientSecret, relays: SIGNER_RELAYS})
|
||||||
|
onNostrConnect: (response: Nip46ResponseWithResult) => void
|
||||||
|
|
||||||
|
constructor({onNostrConnect}: {onNostrConnect: (response: Nip46ResponseWithResult) => void}) {
|
||||||
|
this.onNostrConnect = onNostrConnect
|
||||||
|
}
|
||||||
|
|
||||||
|
async start() {
|
||||||
|
this.url = await this.broker.makeNostrconnectUrl({
|
||||||
|
perms: NIP46_PERMS,
|
||||||
|
url: PLATFORM_URL,
|
||||||
|
name: PLATFORM_NAME,
|
||||||
|
image: PLATFORM_LOGO,
|
||||||
|
})
|
||||||
|
|
||||||
|
let response
|
||||||
|
try {
|
||||||
|
response = await this.broker.waitForNostrconnect(this.url, this.abortController)
|
||||||
|
} catch (errorResponse: any) {
|
||||||
|
if (errorResponse?.error) {
|
||||||
|
pushToast({
|
||||||
|
theme: "error",
|
||||||
|
message: `Received error from signer: ${errorResponse.error}`,
|
||||||
|
})
|
||||||
|
} else if (errorResponse) {
|
||||||
|
console.error(errorResponse)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (response) {
|
||||||
|
this.loading = true
|
||||||
|
this.onNostrConnect(response)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
stop() {
|
||||||
|
this.abortController.abort()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
</script>
|
||||||
|
|
||||||
|
<script lang="ts">
|
||||||
|
import {onMount, onDestroy} from "svelte"
|
||||||
|
import {slideAndFade} from "@lib/transition"
|
||||||
|
import QRCode from "@app/components/QRCode.svelte"
|
||||||
|
import {pushToast} from "@app/toast"
|
||||||
|
|
||||||
|
type Props = {
|
||||||
|
controller: BunkerConnectController
|
||||||
|
}
|
||||||
|
|
||||||
|
const {controller}: Props = $props()
|
||||||
|
|
||||||
|
onMount(() => {
|
||||||
|
controller.start()
|
||||||
|
})
|
||||||
|
|
||||||
|
onDestroy(() => {
|
||||||
|
controller.stop()
|
||||||
|
})
|
||||||
|
</script>
|
||||||
|
|
||||||
|
{#if controller.url}
|
||||||
|
<div class="flex justify-center" out:slideAndFade>
|
||||||
|
<QRCode code={controller.url} />
|
||||||
|
</div>
|
||||||
|
{/if}
|
||||||
32
src/app/components/BunkerUrl.svelte
Normal file
32
src/app/components/BunkerUrl.svelte
Normal file
@@ -0,0 +1,32 @@
|
|||||||
|
<script lang="ts">
|
||||||
|
import {pushModal} from "@app/modal"
|
||||||
|
import InfoBunker from "@app/components/InfoBunker.svelte"
|
||||||
|
import Button from "@lib/components/Button.svelte"
|
||||||
|
import Field from "@lib/components/Field.svelte"
|
||||||
|
import Icon from "@lib/components/Icon.svelte"
|
||||||
|
|
||||||
|
type Props = {
|
||||||
|
bunker: string
|
||||||
|
loading: boolean
|
||||||
|
}
|
||||||
|
|
||||||
|
let {loading, bunker = $bindable("")}: Props = $props()
|
||||||
|
</script>
|
||||||
|
|
||||||
|
<Field>
|
||||||
|
{#snippet label()}
|
||||||
|
<p>Bunker Link*</p>
|
||||||
|
{/snippet}
|
||||||
|
{#snippet input()}
|
||||||
|
<label class="input input-bordered flex w-full items-center gap-2">
|
||||||
|
<Icon icon="cpu" />
|
||||||
|
<input disabled={loading} bind:value={bunker} class="grow" placeholder="bunker://" />
|
||||||
|
</label>
|
||||||
|
{/snippet}
|
||||||
|
{#snippet info()}
|
||||||
|
<p>
|
||||||
|
A login link provided by a nostr signing app.
|
||||||
|
<Button class="link" onclick={() => pushModal(InfoBunker)}>What is a bunker link?</Button>
|
||||||
|
</p>
|
||||||
|
{/snippet}
|
||||||
|
</Field>
|
||||||
@@ -1,112 +1,34 @@
|
|||||||
<script lang="ts">
|
<script lang="ts">
|
||||||
import {onMount, onDestroy} from "svelte"
|
import type {Nip46ResponseWithResult} from "@welshman/signer"
|
||||||
import {Nip46Broker, getPubkey, makeSecret} from "@welshman/signer"
|
import {Nip46Broker, getPubkey, makeSecret} from "@welshman/signer"
|
||||||
import {addSession} from "@welshman/app"
|
import {addSession} from "@welshman/app"
|
||||||
import {preventDefault} from "@lib/html"
|
import {preventDefault} from "@lib/html"
|
||||||
import {slideAndFade} from "@lib/transition"
|
|
||||||
import Spinner from "@lib/components/Spinner.svelte"
|
import Spinner from "@lib/components/Spinner.svelte"
|
||||||
import Button from "@lib/components/Button.svelte"
|
import Button from "@lib/components/Button.svelte"
|
||||||
import Field from "@lib/components/Field.svelte"
|
|
||||||
import Icon from "@lib/components/Icon.svelte"
|
import Icon from "@lib/components/Icon.svelte"
|
||||||
import ModalHeader from "@lib/components/ModalHeader.svelte"
|
import ModalHeader from "@lib/components/ModalHeader.svelte"
|
||||||
import ModalFooter from "@lib/components/ModalFooter.svelte"
|
import ModalFooter from "@lib/components/ModalFooter.svelte"
|
||||||
import QRCode from "@app/components/QRCode.svelte"
|
import BunkerConnect, {BunkerConnectController} from "@app/components/BunkerConnect.svelte"
|
||||||
import InfoBunker from "@app/components/InfoBunker.svelte"
|
import BunkerUrl from "@app/components/BunkerUrl.svelte"
|
||||||
import {loginWithNip46} from "@app/commands"
|
import {loginWithNip46} from "@app/commands"
|
||||||
import {loadUserData} from "@app/requests"
|
import {loadUserData} from "@app/requests"
|
||||||
import {pushModal, clearModals} from "@app/modal"
|
import {clearModals} from "@app/modal"
|
||||||
import {setChecked} from "@app/notifications"
|
import {setChecked} from "@app/notifications"
|
||||||
import {pushToast} from "@app/toast"
|
import {pushToast} from "@app/toast"
|
||||||
import {NIP46_PERMS, PLATFORM_URL, PLATFORM_NAME, PLATFORM_LOGO, SIGNER_RELAYS} from "@app/state"
|
import {SIGNER_RELAYS} from "@app/state"
|
||||||
|
|
||||||
const clientSecret = makeSecret()
|
|
||||||
|
|
||||||
const abortController = new AbortController()
|
|
||||||
|
|
||||||
const broker = Nip46Broker.get({clientSecret, relays: SIGNER_RELAYS})
|
|
||||||
|
|
||||||
const back = () => history.back()
|
const back = () => history.back()
|
||||||
|
|
||||||
const onSubmit = async () => {
|
const controller = new BunkerConnectController({
|
||||||
const {signerPubkey, connectSecret, relays} = Nip46Broker.parseBunkerUrl(bunker)
|
onNostrConnect: async (response: Nip46ResponseWithResult) => {
|
||||||
|
const userPubkey = await controller.broker.getPublicKey()
|
||||||
if (loading) {
|
|
||||||
return
|
|
||||||
}
|
|
||||||
|
|
||||||
if (!signerPubkey || relays.length === 0) {
|
|
||||||
return pushToast({
|
|
||||||
theme: "error",
|
|
||||||
message: "Sorry, it looks like that's an invalid bunker link.",
|
|
||||||
})
|
|
||||||
}
|
|
||||||
|
|
||||||
loading = true
|
|
||||||
|
|
||||||
try {
|
|
||||||
const success = await loginWithNip46({connectSecret, clientSecret, signerPubkey, relays})
|
|
||||||
|
|
||||||
if (success) {
|
|
||||||
abortController.abort()
|
|
||||||
} else {
|
|
||||||
return pushToast({
|
|
||||||
theme: "error",
|
|
||||||
message: "Something went wrong, please try again!",
|
|
||||||
})
|
|
||||||
}
|
|
||||||
} finally {
|
|
||||||
loading = false
|
|
||||||
}
|
|
||||||
|
|
||||||
clearModals()
|
|
||||||
}
|
|
||||||
|
|
||||||
let url = $state("")
|
|
||||||
let bunker = $state("")
|
|
||||||
let loading = $state(false)
|
|
||||||
|
|
||||||
$effect(() => {
|
|
||||||
// For testing and for play store reviewers
|
|
||||||
if (bunker === "reviewkey") {
|
|
||||||
const secret = makeSecret()
|
|
||||||
|
|
||||||
addSession({method: "nip01", secret, pubkey: getPubkey(secret)})
|
|
||||||
}
|
|
||||||
})
|
|
||||||
|
|
||||||
onMount(async () => {
|
|
||||||
url = await broker.makeNostrconnectUrl({
|
|
||||||
perms: NIP46_PERMS,
|
|
||||||
url: PLATFORM_URL,
|
|
||||||
name: PLATFORM_NAME,
|
|
||||||
image: PLATFORM_LOGO,
|
|
||||||
})
|
|
||||||
|
|
||||||
let response
|
|
||||||
try {
|
|
||||||
response = await broker.waitForNostrconnect(url, abortController)
|
|
||||||
} catch (errorResponse: any) {
|
|
||||||
if (errorResponse?.error) {
|
|
||||||
pushToast({
|
|
||||||
theme: "error",
|
|
||||||
message: `Received error from signer: ${errorResponse.error}`,
|
|
||||||
})
|
|
||||||
} else if (errorResponse) {
|
|
||||||
console.error(errorResponse)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
if (response) {
|
|
||||||
loading = true
|
|
||||||
|
|
||||||
const userPubkey = await broker.getPublicKey()
|
|
||||||
|
|
||||||
await loadUserData(userPubkey)
|
await loadUserData(userPubkey)
|
||||||
|
|
||||||
addSession({
|
addSession({
|
||||||
method: "nip46",
|
method: "nip46",
|
||||||
pubkey: userPubkey,
|
pubkey: userPubkey,
|
||||||
secret: clientSecret,
|
secret: controller.clientSecret,
|
||||||
handler: {
|
handler: {
|
||||||
pubkey: response.event.pubkey,
|
pubkey: response.event.pubkey,
|
||||||
relays: SIGNER_RELAYS,
|
relays: SIGNER_RELAYS,
|
||||||
@@ -115,11 +37,49 @@
|
|||||||
|
|
||||||
setChecked("*")
|
setChecked("*")
|
||||||
clearModals()
|
clearModals()
|
||||||
}
|
},
|
||||||
})
|
})
|
||||||
|
|
||||||
onDestroy(() => {
|
const onSubmit = async () => {
|
||||||
abortController.abort()
|
if (controller.loading) return
|
||||||
|
|
||||||
|
const {signerPubkey, connectSecret, relays} = Nip46Broker.parseBunkerUrl(controller.bunker)
|
||||||
|
|
||||||
|
if (!signerPubkey || relays.length === 0) {
|
||||||
|
return pushToast({
|
||||||
|
theme: "error",
|
||||||
|
message: "Sorry, it looks like that's an invalid bunker link.",
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
|
controller.loading = true
|
||||||
|
|
||||||
|
try {
|
||||||
|
const {clientSecret} = controller
|
||||||
|
const success = await loginWithNip46({connectSecret, clientSecret, signerPubkey, relays})
|
||||||
|
|
||||||
|
if (success) {
|
||||||
|
controller.stop()
|
||||||
|
} else {
|
||||||
|
return pushToast({
|
||||||
|
theme: "error",
|
||||||
|
message: "Something went wrong, please try again!",
|
||||||
|
})
|
||||||
|
}
|
||||||
|
} finally {
|
||||||
|
controller.loading = false
|
||||||
|
}
|
||||||
|
|
||||||
|
clearModals()
|
||||||
|
}
|
||||||
|
|
||||||
|
$effect(() => {
|
||||||
|
// For testing and for play store reviewers
|
||||||
|
if (controller.bunker === "reviewkey") {
|
||||||
|
const secret = makeSecret()
|
||||||
|
|
||||||
|
addSession({method: "nip01", secret, pubkey: getPubkey(secret)})
|
||||||
|
}
|
||||||
})
|
})
|
||||||
</script>
|
</script>
|
||||||
|
|
||||||
@@ -132,35 +92,18 @@
|
|||||||
<div>Connect your signer by scanning the QR code below or pasting a bunker link.</div>
|
<div>Connect your signer by scanning the QR code below or pasting a bunker link.</div>
|
||||||
{/snippet}
|
{/snippet}
|
||||||
</ModalHeader>
|
</ModalHeader>
|
||||||
{#if !loading && url}
|
<BunkerConnect {controller} />
|
||||||
<div class="flex justify-center" out:slideAndFade>
|
<BunkerUrl loading={controller.loading} bind:bunker={controller.bunker} />
|
||||||
<QRCode code={url} />
|
|
||||||
</div>
|
|
||||||
{/if}
|
|
||||||
<Field>
|
|
||||||
{#snippet label()}
|
|
||||||
<p>Bunker Link*</p>
|
|
||||||
{/snippet}
|
|
||||||
{#snippet input()}
|
|
||||||
<label class="input input-bordered flex w-full items-center gap-2">
|
|
||||||
<Icon icon="cpu" />
|
|
||||||
<input disabled={loading} bind:value={bunker} class="grow" placeholder="bunker://" />
|
|
||||||
</label>
|
|
||||||
{/snippet}
|
|
||||||
{#snippet info()}
|
|
||||||
<p>
|
|
||||||
A login link provided by a nostr signing app.
|
|
||||||
<Button class="link" onclick={() => pushModal(InfoBunker)}>What is a bunker link?</Button>
|
|
||||||
</p>
|
|
||||||
{/snippet}
|
|
||||||
</Field>
|
|
||||||
<ModalFooter>
|
<ModalFooter>
|
||||||
<Button class="btn btn-link" onclick={back} disabled={loading}>
|
<Button class="btn btn-link" onclick={back} disabled={controller.loading}>
|
||||||
<Icon icon="alt-arrow-left" />
|
<Icon icon="alt-arrow-left" />
|
||||||
Go back
|
Go back
|
||||||
</Button>
|
</Button>
|
||||||
<Button type="submit" class="btn btn-primary" disabled={loading || !bunker}>
|
<Button
|
||||||
<Spinner {loading}>Next</Spinner>
|
type="submit"
|
||||||
|
class="btn btn-primary"
|
||||||
|
disabled={controller.loading || !controller.bunker}>
|
||||||
|
<Spinner loading={controller.loading}>Next</Spinner>
|
||||||
<Icon icon="alt-arrow-right" />
|
<Icon icon="alt-arrow-right" />
|
||||||
</Button>
|
</Button>
|
||||||
</ModalFooter>
|
</ModalFooter>
|
||||||
|
|||||||
Reference in New Issue
Block a user