Skip to content

Releases: appfide/nija

Nija 0.5.0

Choose a tag to compare

@github-actions github-actions released this 16 Oct 10:47
ab1fcea

Unsigned builds: see docs/release.md for Gatekeeper / SmartScreen steps.
Verify downloads with SHA256SUMS.txt, and their origin with
gh attestation verify <file> --repo appfide/nija.
An SPDX bill of materials ships with the release.

What changed in 0.5.0

Added

  • Delete history (Settings → Data): Delete history on this device removes every local clip, pinned ones too, and leaves the database alone; clips already there are not downloaded again. Delete history in the database removes every clip and deletion record from the connected database for all devices. Devices, pairing and keys stay, so sync carries on. In a signed group only the admin, or a member it gave the permission, can do this.
  • Pause a device (Settings → Devices → Manage devices, admin only): a paused device stays paired and keeps its credentials but sends and receives nothing. Clips copied elsewhere while it is paused never reach it, and what it copies meanwhile stays on it. Resume brings it back. Unlike Block, it does not have to be paired again. Devices on 0.4.2 or older do not know this status and keep syncing.
  • Permissions and more admins (Manage devices, admin of a signed group): Permissions… lets a member delete the database history without becoming an admin; Make admin… hands a paired device the group admin key, sealed to it, so it can manage the group too. Both are signed with the membership, so a member cannot grant them to itself. Supabase and PocketBase need two new device columns for this (upgrade notes); without them the app refuses the grant and leaves the device unchanged.
  • Leave this group and Start a new group on this database (Settings → Devices). Leaving removes this device from the group and forgets its credentials and keys; starting a new group wipes the database's clips and devices and makes this device the admin of a fresh group with new keys. The second is also the way back when the admin device is lost.
  • Sync with the database switch (Settings → Sync): turns database sync off on this device only. Clipboard history keeps being recorded locally; nothing copied while it is off is sent, and clips from other devices arrive once it is back on.

Changed

  • Universal Clipboard no longer relabels clips. A copy that reached a Mac or iPhone through Apple's Universal Clipboard was recorded again on that device under its own name, and the original from the device that made it was then dropped as an echo, so every device showed the clip as its own. While syncing, Nija now leaves such copies to the device they came from (Settings → Capture → Leave Universal Clipboard to its device, on by default).
  • A clip can only be deleted from the group by the device that copied it. On every other device the menu now says Delete on this device and only removes the local copy. Before, deleting another device's clip pushed a deletion signed with the wrong key: the database copy was emptied, but signed groups rejected the deletion, so other devices kept the clip and the device that copied it never saw the change. The sync engine now refuses to push such a deletion.
  • Dropping and recreating the database tables no longer disconnects every device. A device whose row is missing now disconnects only if a device it already knew is still listed; otherwise the database was reset, and it registers again (the admin also signs its own row again), whichever device gets back first. Before, each device concluded it had been removed and deleted its credentials and passphrase.
  • Supabase with missing tables or columns now reports Connected plus a schema check listing what is missing, and two ways to fix it. Set up automatically asks once for a Supabase personal access token and runs the setup through the Supabase Management API; the token is sent only to Supabase, for that one request, is never stored, and clipboard capture is paused while the dialog is open so copying it is not recorded. Copy setup SQL gives the same script to run by hand: generated for your table names and sign-in mode, it creates the tables or adds the missing columns, turns on row level security and enables realtime, and is safe to run again. Before, the app said Connection failed: Could not find the table 'public.clip_items' in the schema cache. Sync shows the same advice and retries until the tables exist.
  • A keychain that times out is no longer read as "no keys": this device's signing keys are never replaced because of a slow keychain prompt (peers would reject every clip signed with new ones), and a credential delete the keychain did not confirm is retried rather than coming back on the next launch. Secret fields of the database form are read together, so a pending prompt costs one wait instead of one per field.
  • Supabase personal access tokens (sbp_…) are recognised as credentials: Skip keys and tokens skips them and logs redact them.
  • The macOS app renders with Skia instead of Impeller: on Flutter 3.47 Impeller dropped or garbled single letters in labels.
  • App Store and Mac App Store builds (STORE_BUILD=true, set by scripts/build_appstore.sh) leave out the installers for other platforms and, in the sandboxed Mac build, Start at login. The script now also regenerates the Flutter config before the macOS archive (it used to ship the version of whatever was built last) and puts the provisioning profile on the Release configuration.
  • On iPad and other wide layouts the side rail keeps clear of the status bar; the database tiles no longer overflow on 430 pt wide phones.
  • Store screenshots are generated from the app itself: test_screenshots/store_shots_test.dart renders the screens with demo data, tool/store_shots/compose.py frames them.
  • CI and release builds use Flutter 3.47.5 (from 3.44.4).

What's Changed

  • feat: 0.5.0, data controls, device permissions and store builds by @dhipin in #50

Full Changelog: v0.4.2...v0.5.0

Nija 0.4.2

Choose a tag to compare

@github-actions github-actions released this 30 Sep 05:34
19a3b8c

Unsigned builds: see docs/release.md for Gatekeeper / SmartScreen steps.
Verify downloads with SHA256SUMS.txt, and their origin with
gh attestation verify <file> --repo appfide/nija.
An SPDX bill of materials ships with the release.

What's Changed

  • docs(release): script the macOS signing setup around Apple's portal by @dhipin in #35
  • feat(store): build and upload App Store builds for iOS and macOS by @dhipin in #36
  • feat(history): filters, keyboard control, clip preview and tray recents by @dhipin in #37
  • chore(release): 0.4.2 by @dhipin in #39

Full Changelog: v0.4.1...v0.4.2

Nija 0.4.1

Choose a tag to compare

@github-actions github-actions released this 23 Sep 03:29
ffb3857

Unsigned builds: see docs/release.md for Gatekeeper / SmartScreen steps.
Verify downloads with SHA256SUMS.txt, and their origin with
gh attestation verify <file> --repo appfide/nija.
An SPDX bill of materials ships with the release.

What changed in 0.4.1

Added

  • Every desktop installer is now launched before it is published. Verification proved an installer contained the right app; it could not tell whether that app starts. scripts/smoke_launch.sh unpacks the dmg, deb and Windows zip, starts the binary hidden, and fails the release if it is not still running seconds later — the signature of a build that cannot find a library or dies initialising its database. Android and iOS are not covered: launching them needs an emulator or simulator, and the actions that provide one are not on this repository's allowlist.

What's Changed

  • ci(release): launch every desktop build before publishing it (0.4.1) by @dhipin in #33
  • fix(release): find the Windows executable whatever its case by @dhipin in #34

Full Changelog: v0.4.0...v0.4.1

Nija 0.4.0

Choose a tag to compare

@github-actions github-actions released this 22 Sep 20:11
ad3b028

Unsigned builds: see docs/release.md for Gatekeeper / SmartScreen steps.
Verify downloads with SHA256SUMS.txt, and their origin with
gh attestation verify <file> --repo appfide/nija.
An SPDX bill of materials ships with the release.

What changed in 0.4.0

Changed

  • The app is now called Nija. निज (nija) is Sanskrit for "one's own" — the name says what the product is: your clipboard, on your database, under your keys. The About page and the README explain it. Nothing about how syncing, encryption or pairing works has changed.
  • Bundle identifiers are now com.appfide.nija on every platform (from com.appfide.clipboardSync / com.appfide.clipboard_sync). The operating system treats a new identifier as a different app, so 0.3.0 will not upgrade in place: install Nija, pair it as you would a new device, and remove the old app afterwards. Local history kept by the old install stays in its own sandbox and is not carried over; anything already in your database syncs back down on first run.
  • Pairing codes now start with NIJA1. instead of CSYNC1., and derive from a matching label. A device still running 0.3.0 cannot pair with one running this build — upgrade both.
  • The repository, the Flutter app and the core package are now appfide/nija, apps/nija and packages/nija_core. Live-backend tests read NIJA_TEST_<BACKEND>_* environment variables instead of CLIPSYNC_TEST_*.
  • Noto Sans Devanagari (SIL OFL 1.1) ships with the app so the name renders in its own script on every platform, not only where the OS happens to have a Devanagari face.

Added

  • Every release is now verified before it is published. scripts/verify_artifacts.sh opens each installer and checks it is the app it claims to be — bundle identifier com.appfide.nija, the version being released, a plausible binary size, and the signing state the release promises (Developer ID plus a notarization staple on macOS, a verified upload-key signature on Android). A build carrying the wrong identifier or last version's number now fails the release rather than reaching users.
  • Build provenance. Every published file carries a GitHub-signed attestation naming the workflow, commit and runner that produced it: gh attestation verify <file> --repo appfide/nija. A checksum only proves a file is intact; provenance proves where it came from, which matters because whoever can replace the file can replace the checksum beside it.
  • An SPDX software bill of materials ships with each release and is covered by SHA256SUMS.txt.
  • Release notes now lead with the CHANGELOG section for that version instead of only a list of commit subjects.
  • Releases are serialised: a second version bump queues behind the one in flight instead of racing it for the tag.

Unchanged (deliberately)

  • The passphrase-to-key derivation, the keyed content fingerprint and the key-envelope labels still carry their original clipsync-* v1 names. They are wire constants baked into data already sitting in users' databases: renaming them would make existing clips undecryptable and break de-duplication. The app's name is not part of its key schedule.

What's Changed

  • rename: Clipboard Sync is now Nija (0.4.0) by @dhipin in #25
  • ci(release): build the SBOM without a third-party action by @dhipin in #30
  • fix(release): compare version cores, not packager spellings by @dhipin in #31
  • fix(release): stop grep -q from failing the checks it passes by @dhipin in #32

Full Changelog: v0.3.0...v0.4.0

Clipboard Sync 0.3.0

Choose a tag to compare

@github-actions github-actions released this 22 Sep 11:33
8914421

Unsigned builds: see docs/release.md for Gatekeeper / SmartScreen steps.
Verify downloads with SHA256SUMS.txt.

What's Changed

New Contributors

Full Changelog: https://github.com/appfide/clipboard-sync/compare/v0.2.1...v0.3.0

Clipboard Sync 0.2.1

Choose a tag to compare

@github-actions github-actions released this 11 Sep 10:14
24cc453

Security

  • Key rotation now issues envelopes only to the engine's rollback-aware trusted set. Before, a device whose older admin-signed row had been restored after a block (a rollback the engine already ignored for clips) could still receive the new passphrase. Found by running the attacker suite against a live Supabase project.

Changed

  • Live contract tests allow real websockets time to subscribe; new live_attacker_test.dart runs the signed-group threat model against a real database (dart test -t live).

Unsigned builds — see docs/release.md for Gatekeeper / SmartScreen steps.
Verify downloads with SHA256SUMS.txt.

What's Changed

Full Changelog: https://github.com/appfide/clipboard-sync/compare/v0.2.0...v0.2.1

Clipboard Sync 0.2.0

Choose a tag to compare

@github-actions github-actions released this 11 Sep 08:12
f225111

Added

  • Secure by default: choosing a database now encrypts the group with a random passphrase and signs it with an admin key (switch on the database screen); other devices receive the passphrase sealed through pairing. Settings → Privacy → Show passphrase reveals it for manual joins.
  • Device pairing: Settings → Devices → Add a device shows a QR code (or a copyable code) plus an 8-digit PIN; the other device scans or pastes it under Join another group (also offered on the welcome screen). The code carries the database settings encrypted with the PIN (Argon2id → AES-256-GCM), is valid for 5 minutes and is never recorded in clipboard history. The host chooses the new device's role and access duration and whether to share the passphrase (delivered sealed to the new device, never inside the code).
  • Device management: list every device with presence, block / unblock, remove, forget, change role (Send & receive, Send only, Receive only) and set temporary access. A blocked, removed or expired device stops itself, deletes its credentials, keys and passphrases, and tells the user. In a signed group these decisions are verified cryptographically — see docs/devices.md.
  • Send to… in the history menu pushes a clip to one device only (target_device_id).
  • Capture filters: Pause capture (also in the tray menu), Skip password-manager content (macOS concealed/transient pasteboard types, Windows ExcludeClipboardContentFromMonitorProcessing, Android 13+ EXTRA_IS_SENSITIVE; on by default) and Skip keys and tokens (credential-pattern heuristic).
  • Signed groups: every device has an Ed25519 / X25519 identity; every clip is signed and verified against the sender's admin-signed key; membership changes (status, role, expiry, keys, admin flag, key envelope) are signed by a group admin key with rollback protection. Holding the database credentials is no longer enough to pose as a device, lift a block, or take over the group. Settings → Devices → Secure this group upgrades existing groups; members confirm the admin fingerprint once.
  • Encryption key rotation: the admin issues a fresh random passphrase sealed to each verified device (X25519 + AES-GCM envelope covered by the admin signature). Removed or blocked devices cannot read clips sealed after the rotation; older history stays readable through a local keyring. Pairing delivers the passphrase the same way — it never travels inside the QR code.
  • Device rows carry status, role, expires_at, paired_by, app_version, sign_pub, box_pub, admin, admin_pub, membership_version, membership_sig, key_version, key_envelope; clips carry target_device_id, key_version, sig. Supabase and PocketBase need the upgrade snippet in their guide; other backends need nothing.

Changed

  • Heartbeats write only presence fields, so a block set by another device is never overwritten.
  • Local database schema v2 (adds target_device_id); migrates automatically.

Unsigned builds — see docs/release.md for Gatekeeper / SmartScreen steps.
Verify downloads with SHA256SUMS.txt.

What's Changed

New Contributors

Full Changelog: https://github.com/appfide/clipboard-sync/compare/v0.1.0...v0.2.0

Clipboard Sync 0.1.0

Choose a tag to compare

@github-actions github-actions released this 08 Sep 19:45

Unsigned builds — see docs/release.md for Gatekeeper / SmartScreen steps.
Verify downloads with SHA256SUMS.txt.

Full Changelog: https://github.com/appfide/clipboard-sync/commits/v0.1.0