Commit graph

24 commits

Author SHA1 Message Date
Avi
fac4ba3cde feat(desktop): launch from the applications list (folio-style)
- launch-keynctr.sh: builds renderer/electron main if missing, exports
  KEYNCTR_ENABLE_GPU=1 (software rendering dies 'GPU process isn't
  usable' on this Hyprland box), execs bundled electron with
  --class=keynectr for WM_CLASS grouping.
- keynctr.desktop installed at ~/.local/share/applications/ (validated,
  icon = public/icon.png, categories Utility, StartupWMClass keynectr).
- requestSingleInstanceLock: second launch focuses the existing window
  (app.exit(0) in the doomed instance) instead of a duplicate shell
  fighting the vault.
Verified via gtk-launch: 'keynectr | Keynctr' window maps; second
gtk-launch keeps exactly 1 window.
2026-09-30 09:35:25 -05:00
Avi
dcc701f88b feat(updater): apply updates without restarting the app
New app:selfupdate IPC (main process): npm run build + cargo build --release with the augmented PATH, then kill the backend child, reset the spawn flag so the next request starts the NEW binary, and reloadIgnoringCache every window. The Electron shell keeps running — no manual restart. Settings install now triggers it automatically when restart_required. Honest limits: a change to the Electron main process itself still needs one manual relaunch, and packaged builds report that bundle replacement is the update path.
2026-09-28 09:26:48 -05:00
Avi
81b082f238 feat(signer): always-allow grants for external signer requests
Apps asking Keynctr to sign (NIP-46) can now be granted standing
permission per (peer pubkey, method). Approvals gained an 'Always
allow' option; existing grants are listed with a Revoke button on the
Signer screen and persist in the encrypted vault.
2026-09-12 17:00:41 -05:00
Avi
c5004ebb26 fix(electron): allow nip46_pair_start through the renderer method allowlist
The new QR pairing IPC method was rejected by the main-process allowlist
before reaching the Rust backend ('That operation is not permitted').
2026-09-12 05:01:46 -05:00
Avi
0814a53cb4 fix(linux): work on X11, Wayland, and Hyprland
- detect the session platform explicitly (Hyprland exports both DISPLAY
  and WAYLAND_DISPLAY) and set ozone-platform before Chromium init
- software rendering by default on Linux: the GPU process segfaults in
  eglCreateWindowSurface on some Mesa/Wayland setups (reproduced on
  Intel Iris Xe under Hyprland), so hardware GL is opt-in via
  KEYNCTR_ENABLE_GPU=1
- startup watchdog + bounded relaunch ladder (platform swap, then GPU
  opt-in) when a launch dies before its window paints; give-up dialog
  lists the escape hatches
- sandbox pre-flight: skip the SUID sandbox when user namespaces are
  restricted (Ubuntu 24.04 AppArmor) instead of failing silently
2026-09-09 19:58:38 -05:00
Avi
2c61830390 feat: add per-profile signer modes with persisted NIP-46 connections
Introduce three coexisting signing modes:
- Embedded (INTERNAL): vault-held nsec, decrypted in Rust, signs locally.
- Nip46Client (EXTERNAL): Keynctr is the NIP-46 CLIENT; the key never
  touches this machine.
- Nip46Bunker: legacy inverted mode (Keynctr as signer serving others).

Data model:
- StoredProfile gains signer_mode (serde-defaults to Embedded for legacy
  profiles); SignerMode moves from app.rs to vault.rs to break a circular
  dependency; app.rs re-exports it.
- Vault gains nip46_connections (profile-owned) and bumps VAULT_VERSION to
  3; migrate_vault_signer_modes() normalises on load (idempotent).
- Nip46Connection gains profile_npub ownership, parsed permissions,
  expires_at, and revoked_at.

Signer abstraction (src/signer):
- Signer trait gains pubkey_for() identity validation, a Signing enum
  (Local vs External) that re-verifies the returned event, and a permission
  surface (permissions/can_*/is_connection_valid) with safe defaults.
- permissions.rs: NIP-46 per-connection permission model (parse, validate,
  deny-by-default, no-broadening checks) with 52 unit tests.
- Nip46ClientSigner parses perms from nostrconnect:// URIs, enforces
  permissions on every gated request, persists/revokes connections in the
  vault, and audits permission denials via the app's audit log.
- App gains audit_log and a nip46_bunker_signer handle; default mode is
  Nip46Client (most secure).

Frontend: SignerModeScreen redesigned for the three modes with a
nostr-tools-based SignerManager client, new IPC allowlist entries, and
signer-mode styling.

Verified: cargo test --release 186 passed; clippy/fmt clean; frontend tsc
clean, vitest 110 passed.
2026-09-03 09:47:19 -05:00
Avi
0207636a7a feat: expose profile import over IPC
Wire the existing profiles::import_profile through the JSON-lines IPC
protocol so the GUI can add an existing account: ImportProfile request
and handler in src/ipc.rs, import_profile added to the Electron method
allowlist, api/AppProvider importProfile, and the Add existing account
buttons in ProfilesScreen.

Also add the active signing identity card on Home and fix the HomeScreen
tests whose text queries now match the identity card as well as the
profile row.
2026-09-01 10:41:28 -05:00
Avi
a3b509cb09 feat: rename app to Keynctr 2026-08-31 13:13:47 -05:00
Avi
cbbe779faa Desktop entry + Wayland app id so the taskbar shows the app icon 2026-08-24 11:46:48 -05:00
Avi
8a644afd80 App icon: hummingbird-key mark for window and packaged Linux builds 2026-08-24 11:33:45 -05:00
Avi
8bce42810a Updates card: scan npm/cargo deps, surface security advisories, install compatible updates 2026-08-24 09:54:04 -05:00
Avi
045fa47476 Add NIP-05 identifiers: store, publish, GUI modal, CLI helpers
- Store an optional nip05 on each profile; publish it in kind 0 metadata
- set-nip05 CLI (+ validation, lower-casing, clear) and nip05-file helper
  that prints the .well-known/nostr.json document for a domain
- Profiles screen: NIP-05 button, handle shown on cards, Nip05Modal with
  client-side validation and Remove action
- Fix Modal stealing focus from autoFocus inputs one frame after open
2026-08-23 21:59:11 -05:00
Avi
d618a5a4a0 Add profile rename with metadata republish (GUI + CLI) 2026-08-23 18:48:45 -05:00
Avi
6ead6f418c Fix hardcoded dev window title to Keynectr 2026-08-23 11:04:09 -05:00
Avi
7c6a085bf1 Rename the app to Keynectr
- Crate/binary: nostr-manager-backend -> keynectr
- Data directory: nost-feed-manager -> keynectr, migrated automatically
  on first data_dir() call (existing vaults, settings and backups move)
- Electron extraResources/spawn path, executableName, productName,
  window title and CLI usage strings updated to match
- Deliberately unchanged: crypto.rs KDF verifier string, so previously
  encrypted vault backups remain decryptable

Verified live: existing vault with two profiles migrated to
~/.local/share/keynectr and loads correctly.
2026-08-23 10:22:25 -05:00
Avi
ae5dddaa47 Allow new profile methods through the Electron IPC allowlist
set_profile_picture and publish_profile_metadata were rejected by the
renderer-method gate added in the 2026-08-21 hardening ('rejected renderer
method' in the log), so the GUI buttons could never reach the backend.
Also allow delete_profile / undo_delete from the deletion feature, which
were missing from the list as well.
2026-08-22 20:38:53 -05:00
Avi
f7db29e793 Add SSRF guard, signer queue cap, secret echo, request timeout 2026-08-21 16:06:18 -05:00
Avi
4d4dfde1de Enforce header-based CSP and block window open/navigation 2026-08-21 13:53:45 -05:00
Avi
6e627a3341 Replace upload file paths with single-use pick tokens 2026-08-21 13:48:34 -05:00
Avi
4bde3957b9 Restrict renderer IPC to an explicit method allowlist 2026-08-21 13:30:58 -05:00
Avi
d677125555 Show preview images and link cards in Compose 2026-08-04 13:53:12 -05:00
Avi
03f687717e Sign NIP-98 auth for nostr.build image uploads 2026-08-04 13:37:05 -05:00
Avi
3e3467b006 Add compose preview with image attachments (NIP-92 imeta) 2026-08-04 13:30:30 -05:00
Avi
7e3bac345c Add Nostr Feed Manager: Rust backend with Electron + React GUI
- Rust library (nostr-manager-backend) with CLI and JSON-lines IPC serve mode:
  profiles, publishing with per-relay reports, relays, settings, vault storage
  and legacy-vault migration
- Electron + React + TypeScript desktop GUI using the same backend over stdio IPC
- Vitest suite with a fake backend speaking the real protocol
- electron-builder linux packaging; README with build and usage instructions
2026-08-03 16:05:59 -05:00