From 8c77b10b603d923f280c7a250a871a8469a45bfe Mon Sep 17 00:00:00 2001 From: artur Date: Mon, 19 Feb 2024 09:56:46 +0300 Subject: [PATCH 1/2] Add sw activation logic --- public/manifest.json | 4 ++-- src/App.tsx | 8 +++++++- src/modules/backend.ts | 25 +++++++++++++++---------- src/modules/swic.ts | 20 +++++++++++++++++--- 4 files changed, 41 insertions(+), 16 deletions(-) diff --git a/public/manifest.json b/public/manifest.json index 4f90bb1..b1b64d6 100644 --- a/public/manifest.json +++ b/public/manifest.json @@ -1,6 +1,6 @@ { - "name": "Nsec.app", - "short_name": "Nsec.app - Nostr key management tool", + "name": "Nsec.app - Nostr key management tool", + "short_name": "Nsec.app", "start_url": ".", "icons": [ { diff --git a/src/App.tsx b/src/App.tsx index 4f18330..9105bdb 100644 --- a/src/App.tsx +++ b/src/App.tsx @@ -1,6 +1,6 @@ import { DbKey, dbi } from './modules/db' import { useCallback, useEffect, useState } from 'react' -import { swicOnRender } from './modules/swic' +import { swicOnReload, swicOnRender } from './modules/swic' import { useAppDispatch } from './store/hooks/redux' import { setApps, setKeys, setPending, setPerms } from './store/reducers/content.slice' import AppRoutes from './routes/AppRoutes' @@ -77,6 +77,12 @@ function App() { setRender((r) => r + 1) }) + // subscribe to service worker updates + swicOnReload(() => { + console.log('reload') + // FIXME show 'Please reload' badge at page top + }) + return ( <> diff --git a/src/modules/backend.ts b/src/modules/backend.ts index 145d777..dfb3c20 100644 --- a/src/modules/backend.ts +++ b/src/modules/backend.ts @@ -144,13 +144,8 @@ export class NoauthBackend { const self = this swg.addEventListener('activate', (event) => { - console.log('activate') - // swg.addEventListener('activate', event => event.waitUntil(swg.clients.claim())); - }) - - swg.addEventListener('install', (event) => { - console.log('install') - // swg.addEventListener('install', event => event.waitUntil(swg.skipWaiting())); + console.log('activate new sw worker') + this.reloadUI() }) swg.addEventListener('push', (event) => { @@ -1001,7 +996,7 @@ export class NoauthBackend { } private async editName(npub: string, name: string) { - const key = this.enckeys.find(k => k.npub == npub) + const key = this.enckeys.find(k => k.npub === npub) if (!key) throw new Error("Npub not found"); if (key.name) { await this.sendDeleteNameToServer(npub, key.name) @@ -1015,7 +1010,7 @@ export class NoauthBackend { } private async transferName(npub: string, name: string, newNpub: string) { - const key = this.enckeys.find(k => k.npub == npub) + const key = this.enckeys.find(k => k.npub === npub) if (!key) throw new Error("Npub not found") if (!name) throw new Error("Empty name") if (key.name !== name) throw new Error("Name changed, please reload") @@ -1103,10 +1098,20 @@ export class NoauthBackend { } } + private async reloadUI() { + const clients = await this.swg.clients.matchAll({ + includeUncontrolled: true, + }) + console.log('reloadUI clients', clients.length) + for (const client of clients) { + client.postMessage({ result: 'reload' }) + } + } + public async onPush(event: any) { console.log('push', { data: event.data }) // noop - we just need browser to launch this worker // FIXME use event.waitUntil and and unblock after we - // show a notification + // show a notification to avoid annoying the browser } } diff --git a/src/modules/swic.ts b/src/modules/swic.ts index 725b9ad..3b0ef6e 100644 --- a/src/modules/swic.ts +++ b/src/modules/swic.ts @@ -1,10 +1,12 @@ -// service-worker client interface +// service-worker client interface, +// works on the frontend, not sw import * as serviceWorkerRegistration from '../serviceWorkerRegistration' export let swr: ServiceWorkerRegistration | null = null const reqs = new Map void; rej: (r: any) => void }>() let nextReqId = 1 let onRender: (() => void) | null = null +let onReload: (() => void) | null = null export async function swicRegister() { serviceWorkerRegistration.register({ @@ -13,8 +15,12 @@ export async function swicRegister() { swr = registration }, onError(e) { - console.log(`error ${e}`) + console.log('sw error', e) }, + onUpdate() { + // tell new SW that it should activate immediately + swr?.waiting?.postMessage({type: 'SKIP_WAITING'}) + } }) navigator.serviceWorker.ready.then((r) => { @@ -37,7 +43,11 @@ function onMessage(data: any) { console.log('SW message', id, result, error) if (!id) { - if (onRender) onRender() + if (result === 'reload') { + if (onReload) onReload() + } else { + if (onRender) onRender() + } return } @@ -76,3 +86,7 @@ export async function swicCall(method: string, ...args: any[]) { export function swicOnRender(cb: () => void) { onRender = cb } + +export function swicOnReload(cb: () => void) { + onReload = cb +} From 06fa8ffbd749ef1d0ce0b89a9c73f4bf4f10781e Mon Sep 17 00:00:00 2001 From: artur Date: Mon, 19 Feb 2024 14:10:15 +0300 Subject: [PATCH 2/2] Leave name empty if failed to assign at addKey --- .../Modal/ModalSignUp/ModalSignUp.tsx | 5 +++- src/modules/backend.ts | 24 ++++++++++++++----- 2 files changed, 22 insertions(+), 7 deletions(-) diff --git a/src/components/Modal/ModalSignUp/ModalSignUp.tsx b/src/components/Modal/ModalSignUp/ModalSignUp.tsx index f3165fc..d9cff4c 100644 --- a/src/components/Modal/ModalSignUp/ModalSignUp.tsx +++ b/src/components/Modal/ModalSignUp/ModalSignUp.tsx @@ -60,7 +60,10 @@ export const ModalSignUp = () => { try { setIsLoading(true) const k: any = await swicCall('generateKey', name) - notify(`Account created for "${name}"`, 'success') + if (k.name) + notify(`Account created for "${k.name}"`, 'success') + else + notify(`Failed to assign name "${name}", try again`, 'error') setIsLoading(false) setTimeout(() => { // give frontend time to read the new key first diff --git a/src/modules/backend.ts b/src/modules/backend.ts index 3a03fdc..2bbcc1e 100644 --- a/src/modules/backend.ts +++ b/src/modules/backend.ts @@ -28,6 +28,7 @@ enum DECISION { export interface KeyInfo { npub: string nip05?: string + name?: string locked: boolean } @@ -366,7 +367,7 @@ export class NoauthBackend { if (r.status !== 200 && r.status !== 201) { console.log('Fetch error', url, method, r.status) const body = await r.json() - throw new Error('Failed to fetch ' + url, { cause: body }) + throw new Error('Failed to fetch ' + url, { cause: { body, status: r.status } }) } return await r.json() @@ -501,7 +502,7 @@ export class NoauthBackend { }) } catch (e: any) { console.log('error', e.cause) - if (e.cause && e.cause.minPow > pow) pow = e.cause.minPow + if (e.cause && e.cause.body && e.cause.body.minPow > pow) pow = e.cause.body.minPow else throw e } } @@ -637,6 +638,7 @@ export class NoauthBackend { return { npub: k.npub, nip05: k.nip05, + name: k.name, locked: this.isLocked(k.npub), } } @@ -677,11 +679,16 @@ export class NoauthBackend { await this.startKey({ npub, sk }) // assign nip05 before adding the key - // FIXME set name to db and if this call to 'send' fails - // then retry later if (!existingName && name && !name.includes('@')) { console.log('adding key', npub, name) - await this.sendNameToServer(npub, name) + try { + await this.sendNameToServer(npub, name) + } catch (e) { + console.log('create name failed', e) + // clear it + await dbi.editName(npub, '') + dbKey.name = '' + } } const sub = await this.swg.registration.pushManager.getSubscription() @@ -1155,7 +1162,12 @@ export class NoauthBackend { const key = this.enckeys.find((k) => k.npub == npub) if (!key) throw new Error('Npub not found') if (key.name) { - await this.sendDeleteNameToServer(npub, key.name) + try { + await this.sendDeleteNameToServer(npub, key.name) + } catch (e: any) { + if (e.cause && e.cause.status !== 404) throw e + console.log("Deleted name didn't exist") + } } if (name) { await this.sendNameToServer(npub, name)