diff --git a/.github/workflows/docker-image.yml b/.github/workflows/docker-image.yml deleted file mode 100644 index 6462033..0000000 --- a/.github/workflows/docker-image.yml +++ /dev/null @@ -1,61 +0,0 @@ -name: Docker image - -on: - push: - branches: - - '**' - tags: - - 'v*.*.*' - pull_request: - branches: - - 'master' - -env: - REGISTRY: ghcr.io - IMAGE_NAME: ${{ github.repository }} - -jobs: - build-and-push-image: - runs-on: ubuntu-latest - permissions: - contents: read - packages: write - - steps: - - name: Checkout repository - uses: actions/checkout@v4 - - - name: Set up QEMU - uses: docker/setup-qemu-action@v3 - - - name: Set up Docker Buildx - uses: docker/setup-buildx-action@v3 - - - name: Log in to the Container registry - uses: docker/login-action@v3 - with: - registry: ${{ env.REGISTRY }} - username: ${{ github.actor }} - password: ${{ secrets.GITHUB_TOKEN }} - - - name: Extract metadata (tags, labels) for Docker - id: meta - uses: docker/metadata-action@v5 - with: - images: ${{ env.REGISTRY }}/${{ env.IMAGE_NAME }} - tags: | - type=semver,pattern={{version}} - type=semver,pattern={{major}}.{{minor}} - type=semver,pattern={{major}} - type=ref,event=branch - type=ref,event=pr - type=sha - - - name: Build and push Docker image - uses: docker/build-push-action@v5 - with: - context: . - push: true - platforms: linux/amd64,linux/arm64 - tags: ${{ steps.meta.outputs.tags }} - labels: ${{ steps.meta.outputs.labels }} diff --git a/.gitignore b/.gitignore index f3a073a..ce46655 100644 --- a/.gitignore +++ b/.gitignore @@ -7,5 +7,3 @@ nsecbunker.json connection.txt config .env -.turbo -prisma diff --git a/.prettierrc.json b/.prettierrc.json index f98859f..2519bad 100644 --- a/.prettierrc.json +++ b/.prettierrc.json @@ -1,15 +1,7 @@ { - "importOrder": ["^[./]"], - "importOrderSeparation": true, - "tabWidth": 4, - "useTabs": false, - "semi": true, - "overrides": [ - { - "files": "*.handlebar", - "options": { - "tabWidth": 2 - } - } - ] + "importOrder": ["^[./]"], + "importOrderSeparation": true, + "tabWidth": 4, + "useTabs": false, + "semi": true } diff --git a/package.json b/package.json index 4232435..a76b41c 100644 --- a/package.json +++ b/package.json @@ -1,6 +1,6 @@ { "name": "nsecbunkerd", - "version": "0.10.5", + "version": "0.10.3", "description": "nsecbunker daemon", "main": "dist/index.js", "bin": { @@ -39,7 +39,7 @@ "@fastify/view": "^8.2.0", "@inquirer/password": "^1.1.2", "@inquirer/prompts": "^1.2.3", - "@nostr-dev-kit/ndk": "workspace:*", + "@nostr-dev-kit/ndk": "^2.4.2", "@prisma/client": "^5.4.1", "@scure/base": "^1.1.1", "@types/yargs": "^17.0.24", diff --git a/pnpm-lock.yaml b/pnpm-lock.yaml index c3fd1d1..f5678c2 100644 --- a/pnpm-lock.yaml +++ b/pnpm-lock.yaml @@ -18,8 +18,8 @@ dependencies: specifier: ^1.2.3 version: 1.2.3 '@nostr-dev-kit/ndk': - specifier: ^2.8.1 - version: 2.8.1(typescript@5.1.3) + specifier: ^2.4.2 + version: 2.4.2(typescript@5.1.3) '@prisma/client': specifier: ^5.4.1 version: 5.4.1(prisma@5.4.1) @@ -46,10 +46,10 @@ dependencies: version: 16.3.1 eslint-config-prettier: specifier: ^8.8.0 - version: 8.8.0(eslint@8.57.0) + version: 8.8.0(eslint@8.56.0) eslint-plugin-import: specifier: ^2.27.5 - version: 2.27.5(eslint@8.57.0) + version: 2.27.5(eslint@8.56.0) eventemitter3: specifier: ^5.0.1 version: 5.0.1 @@ -316,13 +316,13 @@ packages: dev: true optional: true - /@eslint-community/eslint-utils@4.4.0(eslint@8.57.0): + /@eslint-community/eslint-utils@4.4.0(eslint@8.56.0): resolution: {integrity: sha512-1/sA4dwrzBAyeUoQ6oxahHKmrZvsnLCg4RfxW3ZFGGmQkSNQPFNLV9CUEFQP1x9EYXHTo5p6xdhZM1Ne9p/AfA==} engines: {node: ^12.22.0 || ^14.17.0 || >=16.0.0} peerDependencies: eslint: ^6.0.0 || ^7.0.0 || >=8.0.0 dependencies: - eslint: 8.57.0 + eslint: 8.56.0 eslint-visitor-keys: 3.4.3 dev: false @@ -348,8 +348,8 @@ packages: - supports-color dev: false - /@eslint/js@8.57.0: - resolution: {integrity: sha512-Ys+3g2TaW7gADOJzPt83SJtCDhMjndcDMFVQ/Tj9iA1BfJzFKD9mAUXT3OenpuPHbI6P/myECxRJrofUsDx/5g==} + /@eslint/js@8.56.0: + resolution: {integrity: sha512-gMsVel9D7f2HLkBma9VbtzZRehRogVRfbr++f06nL2vnCGCNlzOD+/MUov/F4p8myyAHspEhVobgjpX64q5m6A==} engines: {node: ^12.22.0 || ^14.17.0 || >=16.0.0} dev: false @@ -393,7 +393,7 @@ packages: resolution: {integrity: sha512-3T8LkOmg45BV5FICb15QQMsyUSWrQ8AygVfC7ZG32zOalnqrilm018ZVCw0eapXux8FtA33q8PSRSstjee3jSg==} engines: {node: '>=10.10.0'} dependencies: - '@humanwhocodes/object-schema': 2.0.3 + '@humanwhocodes/object-schema': 2.0.2 debug: 4.3.4 minimatch: 3.1.2 transitivePeerDependencies: @@ -405,8 +405,8 @@ packages: engines: {node: '>=12.22'} dev: false - /@humanwhocodes/object-schema@2.0.3: - resolution: {integrity: sha512-93zYdMES/c1D69yZiKDBj0V24vqNzB/koF26KPaagAfd3P/4gUlh3Dys5ogAK+Exi9QyzlD8x/08Zt7wIKcDcA==} + /@humanwhocodes/object-schema@2.0.2: + resolution: {integrity: sha512-6EwiSjwWYP7pTckG6I5eyFANjPhmPjUX9JRLUSfNPC7FX7zK9gyZAfUEaECL6ALTpGX5AjnBq3C9XmVWPitNpw==} dev: false /@inquirer/checkbox@1.3.2: @@ -599,12 +599,6 @@ packages: '@noble/hashes': 1.3.1 dev: false - /@noble/curves@1.4.0: - resolution: {integrity: sha512-p+4cb332SFCrReJkCYe8Xzm0OWi4Jji5jVdIZRL/PmacmDkFNw6MrrV+gGpiPxLHbV+zKFRywUWbaseT+tZRXg==} - dependencies: - '@noble/hashes': 1.4.0 - dev: false - /@noble/hashes@1.3.1: resolution: {integrity: sha512-EbqwksQwz9xDRGfDST86whPBgM65E0OH/pCgqW0GBVzO22bNE+NuIbeTb714+IfSjU3aRk47EUvXIb5bTsenKA==} engines: {node: '>= 16'} @@ -615,13 +609,13 @@ packages: engines: {node: '>= 16'} dev: false - /@noble/hashes@1.4.0: - resolution: {integrity: sha512-V1JJ1WTRUqHHrOSh597hURcMqVKVGL/ea3kv0gSnEdsEZ0/+VyPghM1lMNGc00z7CIQorSvbKpuJkxvuHbvdbg==} + /@noble/hashes@1.3.3: + resolution: {integrity: sha512-V7/fPHgl+jsVPXqqeOzT8egNj2iBIVt+ECeMMG8TdcnTikP3oaBtUVqpT/gYCR68aEBJSF+XbYUxStjbFMqIIA==} engines: {node: '>= 16'} dev: false - /@noble/secp256k1@2.1.0: - resolution: {integrity: sha512-XLEQQNdablO0XZOIniFQimiXsZDNwaYgL96dZwC54Q30imSbAOFf3NKtepc+cXyuZf5Q1HCgbqgZ2UFFuHVcEw==} + /@noble/secp256k1@2.0.0: + resolution: {integrity: sha512-rUGBd95e2a45rlmFTqQJYEFA4/gdIARFfuTuTqLglz0PZ6AKyzyXsEZZq7UZn8hZsvaBgpCzKKBJizT2cJERXw==} dev: false /@nodelib/fs.scandir@2.1.5: @@ -642,15 +636,14 @@ packages: '@nodelib/fs.scandir': 2.1.5 fastq: 1.15.0 - /@nostr-dev-kit/ndk@2.8.1(typescript@5.1.3): - resolution: {integrity: sha512-2WPN1FVhxcLxFYwva2Ti6XKQUjqU0jfdoHHhqDF+0Mxp8f/uDyLflsUQCXsZym5rOIHY85eCYhAXi6V6q6gpRg==} + /@nostr-dev-kit/ndk@2.4.2(typescript@5.1.3): + resolution: {integrity: sha512-78gHKyPVy2u6obnTmOU9dMJMi07LgzoTQtO1RjWkcwlQvPyjbpCQ4EXjDSM1pmdj7narwW+uJibnld6z8dT1Fg==} dependencies: - '@noble/curves': 1.4.0 - '@noble/hashes': 1.4.0 - '@noble/secp256k1': 2.1.0 + '@noble/hashes': 1.3.3 + '@noble/secp256k1': 2.0.0 '@scure/base': 1.1.1 debug: 4.3.4 - light-bolt11-decoder: 3.1.1 + light-bolt11-decoder: 3.0.0 node-fetch: 3.3.2 nostr-tools: 1.17.0(typescript@5.1.3) tseep: 1.2.1 @@ -1471,13 +1464,13 @@ packages: engines: {node: '>=10'} dev: false - /eslint-config-prettier@8.8.0(eslint@8.57.0): + /eslint-config-prettier@8.8.0(eslint@8.56.0): resolution: {integrity: sha512-wLbQiFre3tdGgpDv67NQKnJuTlcUVYHas3k+DZCc2U2BadthoEY4B7hLPvAxaqdyOGCzuLfii2fqGph10va7oA==} hasBin: true peerDependencies: eslint: '>=7.0.0' dependencies: - eslint: 8.57.0 + eslint: 8.56.0 dev: false /eslint-import-resolver-node@0.3.7: @@ -1490,7 +1483,7 @@ packages: - supports-color dev: false - /eslint-module-utils@2.8.0(eslint-import-resolver-node@0.3.7)(eslint@8.57.0): + /eslint-module-utils@2.8.0(eslint-import-resolver-node@0.3.7)(eslint@8.56.0): resolution: {integrity: sha512-aWajIYfsqCKRDgUfjEXNN/JlrzauMuSEy5sbd7WXbtW3EH6A6MpwEh42c7qD+MqQo9QMJ6fWLAeIJynx0g6OAw==} engines: {node: '>=4'} peerDependencies: @@ -1512,13 +1505,13 @@ packages: optional: true dependencies: debug: 3.2.7 - eslint: 8.57.0 + eslint: 8.56.0 eslint-import-resolver-node: 0.3.7 transitivePeerDependencies: - supports-color dev: false - /eslint-plugin-import@2.27.5(eslint@8.57.0): + /eslint-plugin-import@2.27.5(eslint@8.56.0): resolution: {integrity: sha512-LmEt3GVofgiGuiE+ORpnvP+kAm3h6MLZJ4Q5HCyHADofsb4VzXFsRiWj3c0OFiV+3DWFh0qg3v9gcPlfc3zRow==} engines: {node: '>=4'} peerDependencies: @@ -1533,9 +1526,9 @@ packages: array.prototype.flatmap: 1.3.1 debug: 3.2.7 doctrine: 2.1.0 - eslint: 8.57.0 + eslint: 8.56.0 eslint-import-resolver-node: 0.3.7 - eslint-module-utils: 2.8.0(eslint-import-resolver-node@0.3.7)(eslint@8.57.0) + eslint-module-utils: 2.8.0(eslint-import-resolver-node@0.3.7)(eslint@8.56.0) has: 1.0.3 is-core-module: 2.12.1 is-glob: 4.0.3 @@ -1563,15 +1556,15 @@ packages: engines: {node: ^12.22.0 || ^14.17.0 || >=16.0.0} dev: false - /eslint@8.57.0: - resolution: {integrity: sha512-dZ6+mexnaTIbSBZWgou51U6OmzIhYM2VcNdtiTtI7qPNZm35Akpr0f6vtw3w1Kmn5PYo+tZVfh13WrhpS6oLqQ==} + /eslint@8.56.0: + resolution: {integrity: sha512-Go19xM6T9puCOWntie1/P997aXxFsOi37JIHRWI514Hc6ZnaHGKY9xFhrU65RT6CcBEzZoGG1e6Nq+DT04ZtZQ==} engines: {node: ^12.22.0 || ^14.17.0 || >=16.0.0} hasBin: true dependencies: - '@eslint-community/eslint-utils': 4.4.0(eslint@8.57.0) + '@eslint-community/eslint-utils': 4.4.0(eslint@8.56.0) '@eslint-community/regexpp': 4.10.0 '@eslint/eslintrc': 2.1.4 - '@eslint/js': 8.57.0 + '@eslint/js': 8.56.0 '@humanwhocodes/config-array': 0.11.14 '@humanwhocodes/module-importer': 1.0.1 '@nodelib/fs.walk': 1.2.8 @@ -1826,7 +1819,7 @@ packages: engines: {node: ^12.20 || >= 14.13} dependencies: node-domexception: 1.0.0 - web-streams-polyfill: 3.3.3 + web-streams-polyfill: 3.3.2 dev: false /figures@3.2.0: @@ -1886,13 +1879,13 @@ packages: resolution: {integrity: sha512-CYcENa+FtcUKLmhhqyctpclsq7QF38pKjZHsGNiSQF5r4FtoKDWabFDl3hzaEQMvT1LHEysw5twgLvpYYb4vbw==} engines: {node: ^10.12.0 || >=12.0.0} dependencies: - flatted: 3.3.1 + flatted: 3.2.9 keyv: 4.5.4 rimraf: 3.0.2 dev: false - /flatted@3.3.1: - resolution: {integrity: sha512-X8cqMLLie7KsNUDSdzeN8FYK9rEt4Dt67OsG/DNGnYTSDBG4uFAJFBnUeiV+zCVAvwFy56IjM9sH51jVaEhNxw==} + /flatted@3.2.9: + resolution: {integrity: sha512-36yxDn5H7OFZQla0/jFJmbIKTdZAQHngCedGxiMmpNfEZM0sdEeT+WczLQrjK6D7o2aiyLYDnkw0R3JK0Qv1RQ==} dev: false /follow-redirects@1.15.3(debug@4.3.4): @@ -2436,8 +2429,8 @@ packages: type-check: 0.4.0 dev: false - /light-bolt11-decoder@3.1.1: - resolution: {integrity: sha512-sLg/KCwYkgsHWkefWd6KqpCHrLFWWaXTOX3cf6yD2hAzL0SLpX+lFcaFK2spkjbgzG6hhijKfORDc9WoUHwX0A==} + /light-bolt11-decoder@3.0.0: + resolution: {integrity: sha512-AKvOigD2pmC8ktnn2TIqdJu0K0qk6ukUmTvHwF3JNkm8uWCqt18Ijn33A/a7gaRZ4PghJ59X+8+MXrzLKdBTmQ==} dependencies: '@scure/base': 1.1.1 dev: false @@ -3600,8 +3593,8 @@ packages: engines: {node: '>= 0.8'} dev: false - /web-streams-polyfill@3.3.3: - resolution: {integrity: sha512-d2JWLCivmZYTSIoge9MsgFCZrt571BikcWGYkjC1khllbTeDlGqZ2D8vD8E/lJa8WGWbb7Plm8/XJYV7IJHZZw==} + /web-streams-polyfill@3.3.2: + resolution: {integrity: sha512-3pRGuxRF5gpuZc0W+EpwQRmCD7gRqcDOMt688KmdlDAgAyaB1XlN0zq2njfDNm44XVdIouE7pZ6GzbdyH47uIQ==} engines: {node: '>= 8'} dev: false diff --git a/scripts/start.ts b/scripts/start.ts deleted file mode 100644 index 41c2396..0000000 --- a/scripts/start.ts +++ /dev/null @@ -1,22 +0,0 @@ -import { execSync, spawn } from "child_process"; - -try { - console.log(`Running migrations`); - // check if config folder exists - if (!fs.existsSync('./config')) { - execSync(`mkdir config`); - } - execSync('npm run prisma:migrate'); -} catch (error) { - console.log(error); - // Handle any potential migration errors here -} - -const args = process.argv.slice(2); -const childProcess = spawn('node', ['./dist/index.js', ...args], { - stdio: 'inherit', -}); - -childProcess.on('exit', (code) => { - process.exit(code); -}); diff --git a/src/client.ts b/src/client.ts index 0fcad60..3159589 100644 --- a/src/client.ts +++ b/src/client.ts @@ -76,8 +76,6 @@ function loadPrivateKey(): string | undefined { (async () => { let remoteUser: NDKUser; - ndk = await createNDK(); - // if this is the create_account command and we have something that doesn't look like an npub as the remotePubkey, use NDKUser.fromNip05 to get the npub if (command === 'create_account' && !remotePubkey.startsWith("npub")) { // see if we have a username@domain @@ -90,7 +88,7 @@ function loadPrivateKey(): string | undefined { content = `${username},${domain}` - const u = await NDKUser.fromNip05(domain, ndk); + const u = await NDKUser.fromNip05(domain); if (!u) { console.log(`Invalid nip05 ${remotePubkey}`); process.exit(1); @@ -112,7 +110,7 @@ function loadPrivateKey(): string | undefined { } } - + ndk = await createNDK(); let localSigner: NDKPrivateKeySigner; const pk = loadPrivateKey(); diff --git a/src/commands/start.ts b/src/commands/start.ts index 0c7f835..8e39430 100644 --- a/src/commands/start.ts +++ b/src/commands/start.ts @@ -27,10 +27,8 @@ async function nip89announcement(configData: IConfig) { const relays = config.nip89!.relays; const nip05 = `_@${domain}`; - const ndk = new NDK({explicitRelayUrls: relays}); - // make sure the nip05 correctly points to this pubkey - const uservianip05 = await NDKUser.fromNip05(nip05, ndk); + const uservianip05 = await NDKUser.fromNip05(nip05); if (!uservianip05 || uservianip05.pubkey !== signerUser.pubkey) { console.log(`❌ ${nip05} does not point to this nsecbunker's key`); if (uservianip05) { @@ -55,6 +53,7 @@ async function nip89announcement(configData: IConfig) { const hasWallet = !!config.wallet; const hasNostrdress = !!config.wallet?.lnbits?.nostdressUrl; + const ndk = new NDK({explicitRelayUrls: relays}); ndk.signer = signer; ndk.connect(5000).then(async () => { const event = new NDKAppHandlerEvent(ndk, { diff --git a/src/daemon/admin/index.ts b/src/daemon/admin/index.ts index 4db9cc2..a583f36 100644 --- a/src/daemon/admin/index.ts +++ b/src/daemon/admin/index.ts @@ -1,5 +1,5 @@ import "websocket-polyfill"; -import NDK, { NDKEvent, NDKKind, NDKPrivateKeySigner, NDKRpcRequest, NDKRpcResponse, NDKUser, NostrEvent } from '@nostr-dev-kit/ndk'; +import NDK, { NDKKind, NDKPrivateKeySigner, NDKRpcRequest, NDKRpcResponse, NDKUser } from '@nostr-dev-kit/ndk'; import { NDKNostrRpc } from '@nostr-dev-kit/ndk'; import createDebug from 'debug'; import { Key, KeyUser } from '../run'; @@ -121,8 +121,6 @@ class AdminInterface { }); this.rpc.on('request', (req) => this.handleRequest(req)); - - pingOrDie(this.ndk); }).catch((err) => { console.log('❌ admin connection failed'); console.log(err); @@ -395,44 +393,4 @@ class AdminInterface { } } -async function pingOrDie(ndk: NDK) { - let deathTimer: NodeJS.Timeout | null = null; - - function resetDeath() { - if (deathTimer) clearTimeout(deathTimer); - deathTimer = setTimeout(() => { - console.log(`❌ No ping event received in 30 seconds. Exiting.`); - process.exit(1); - }, 50000); - } - - const self = await ndk.signer!.user(); - const sub = ndk.subscribe({ - authors: [self.pubkey], - kinds: [NDKKind.NostrConnect], - "#p": [self.pubkey] - }); - sub.on("event", (event: NDKEvent) => { - console.log(`🔔 Received ping event:`, event.created_at); - resetDeath(); - }); - sub.start(); - - resetDeath(); - - setInterval(() => { - const event = new NDKEvent(ndk, { - kind: NDKKind.NostrConnect, - tags: [ ["p", self.pubkey] ], - content: "ping" - } as NostrEvent); - event.publish().then(() => { - console.log(`🔔 Sent ping event:`, event.created_at); - }).catch((e: any) => { - console.log(`❌ Failed to send ping event:`, e.message); - process.exit(1); - }); - }, 20000); -} - export default AdminInterface; diff --git a/src/daemon/backend/index.ts b/src/daemon/backend/index.ts index 7661a09..5dd240a 100644 --- a/src/daemon/backend/index.ts +++ b/src/daemon/backend/index.ts @@ -1,4 +1,4 @@ -import NDK, { NDKNip46Backend, NDKPrivateKeySigner, Nip46PermitCallback } from '@nostr-dev-kit/ndk'; +import NDK, { NDKNip46Backend, Nip46PermitCallback } from '@nostr-dev-kit/ndk'; import prisma from '../../db.js'; import type {FastifyInstance} from "fastify"; @@ -13,8 +13,7 @@ export class Backend extends NDKNip46Backend { cb: Nip46PermitCallback, baseUrl?: string ) { - const signer = new NDKPrivateKeySigner(key); - super(ndk, signer, cb); + super(ndk, key, cb); this.baseUrl = baseUrl; this.fastify = fastify; diff --git a/src/daemon/run.ts b/src/daemon/run.ts index 262a150..ec5b16a 100644 --- a/src/daemon/run.ts +++ b/src/daemon/run.ts @@ -226,20 +226,7 @@ class Daemon { */ async startKey(name: string, nsec: string) { const cb = signingAuthorizationCallback(name, this.adminInterface); - let hexpk: string; - - if (nsec.startsWith('nsec1')) { - try { - const key = new NDKPrivateKeySigner(nsec); - hexpk = key.privateKey!; - } catch(e) { - console.error(`Error loading key ${name}:`, e); - return - } - } else { - hexpk = nsec; - } - + const hexpk = nip19.decode(nsec).data as string; const backend = new Backend(this.ndk, this.fastify, hexpk, cb, this.config.baseUrl); await backend.start(); } diff --git a/templates/authorizeRequest.handlebar b/templates/authorizeRequest.handlebar index 3f9f0d4..b01f3f7 100644 --- a/templates/authorizeRequest.handlebar +++ b/templates/authorizeRequest.handlebar @@ -1,8 +1,8 @@ - - + + Authorize Request @@ -75,12 +75,11 @@ .catch((error) => { console.error('Error:', error); }); - }; + } + class="flex flex-col justify-center items-center min-h-screen bg-gray-100 dark:bg-neutral-800 text-neutrla-950 dark:text-neutral-50">

+ class="text-neutral-950 dark:text-neutral-50 text-lg font-semibold w-full"> Do you want to allow this client to use account
- {{ record.keyName }}? + {{record.keyName}}?

- + {{#unless authenticated}}
@@ -133,14 +124,12 @@
@@ -157,7 +146,7 @@