Skip to content
zccz14Public

About

Linkit is an Auth Mini-powered profile and instant messaging app.

Resources

Stars

1 star

Watchers

0 watching

Forks

Repository files navigation

Linkit

Linkit is an open-source, Auth Mini-powered profile and instant-messaging app distributed as one Rust binary. It includes user profiles, a searchable directory, direct messages, group conversations, media attachments, direct Bark/APNs notifications, native Bot API tokens, and personal API keys that let scripts speak as a human user.

Features

  • Profiles and people directory — username, avatar, intro, and search.
  • Messaging — direct and group conversations, @ mentions, image/file attachments, read state, cursor-paged history, and immediate SSE message and unread refresh.
  • @ mentions — type @ in the composer to pick a conversation member or bot; the picker fuzzy-matches usernames, bot names, and your private note names, and every candidate shows its avatar, name, and your private note. Messages store mentions as <@user_id> tokens, clients render them as @username, and a mentioned member's Bark notification says they were mentioned.
  • Open-page links — external apps may open /?open=profile to edit the profile or /?open=message&username=alice to begin a direct message.
  • Direct Bark notifications — an iPhone running Bark binds directly to its Linkit user and receives APNs notifications without Linkit exposing a public Bark push API.
  • Bilingual UI — English and Chinese interfaces, with an in-app language picker and browser-language default on first visit.
  • Native Bots — each Bot is a users principal with a durable UUID, one human control owner, an sk-… bearer token, owner transfer, and token rotation. A Bot uses the same profile and conversation APIs as a user, and its owner can open a read-only view of the Bot's conversations. Any group member can add users to a group, including their own Bots; only the group owner can remove members.
  • User API keys — personal uk-… tokens created on the API keys page authenticate as their creating human on the normal routes, so scripts can send messages as you; revocation is immediate.
  • Native iOS app — a SwiftUI client under ios/ with Auth Mini sign-in, direct and group messaging, mentions, attachments, live SSE updates and profile preferences.
  • Auth Mini — setup verifies its root_user_id against an Auth Mini JWT; authenticated requests validate JWTs against the configured issuer and audience, then silently ensure the user's account and default profile exist. No separate registration form is required.

Quick start

Download the matching archive from the latest GitHub Release, verify its SHA-256 checksum, extract it, and run ./linkit.

The app listens on 0.0.0.0:8080, serves the embedded Web UI, and creates its private SQLite database and attachment store under ~/.linkit/. No environment variables are required.

Open the app, enter your Auth Mini issuer, app hostname audience, public origin, and Auth Mini subject as root_user_id, then sign in with the matching user and initialize the instance. The default production issuer is https://auth.ntnl.io.

Silent account and profile creation

Every valid Auth Mini JWT on a protected API request passes through a shared ensure operation before the route runs. New users receive a Linkit account and a profile with an editable user_<12 hexadecimal characters> username. Existing profiles are never overwritten; missing profiles are repaired automatically. This works without configuring a directory token or visiting the Linkit UI.

See the provisioning contract for concurrency, collision handling and authorization boundaries.

Auth Mini user synchronization

The Root User can configure an Auth Mini user ID directory token under System → Auth Mini user sync. Linkit silently provisions missing human accounts and default profiles immediately, on startup and every 60 seconds, using only Auth Mini user IDs and without receiving other Auth Mini user data. See the configuration and API guide.

Bot API

Create a Bot as its owner in the Linkit UI. The generated token is shown exactly once and starts with sk-. The token authenticates the Bot at the normal /api routes. For example, create a group as the Bot:

curl https://linkit.ntnl.io/api/conversations \
  -H 'Authorization: Bearer sk-…' \
  -H 'Content-Type: application/json' \
  -d '{"title":"Fund investors","user_ids":["user-uuid"]}'

A Bot can create and own groups, add or remove their members, update its own profile, open direct conversations, and send messages through the corresponding normal user routes. Only /api/bots and /api/user-api-keys remain human-only control planes: Bots cannot create, rotate, transfer, or delete Bots, and cannot manage user API keys.

The Bots page also opens a read-only perspective of a Bot's conversations. The browser keeps the owner's Auth Mini session and adds the Bot's user ID to read requests as ?act_as=<bot_user_id>; Linkit accepts act_as only on GET requests and only for a Bot owned by the authenticated user.

See the Bot direct-message guide for the full creation flow, token handling, response contract, and error handling.

User API keys

A human creates uk-… keys on the API keys page. A key authenticates as the human who created it, so scripts and tools use the normal routes with that user's own identity — the same profile, conversations, mentions, read state and notifications as the web UI:

curl --fail-with-body https://linkit.ntnl.io/api/conversations/CONVERSATION_ID/messages \
  -H 'Authorization: Bearer uk-…' \
  -H 'Content-Type: application/json' \
  -d '{"body":"Status report from my scripts.","attachment_ids":[],"urgent":false}'

Tokens are shown exactly once, stored as hashes, and a revoked key fails on its next request. See the user API key guide for the creation flow, management API and boundaries.

External profile lookup

Downstream products may resolve a known Auth Mini user ID to Linkit's minimal public profile: username, intro, and an optional safe avatar URL. It does not expose messages or notification data. Signed-in clients may use the separately documented bounded username search API. See the external profile API guide.

Bark device binding

Linkit sends conversation and Bot notifications directly to Bark on iPhone through APNs. It does not expose Bark URL V1/V2 push endpoints.

Open Settings → Notifications while signed in to obtain your private Bark Server Base URL and QR code. In Bark on iPhone, add a server and scan that QR code. Bark calls the Base URL's /ping and /register endpoints; registration uploads its APNs device token and Linkit binds that device to the signed-in Linkit user who owns the Base URL.

The Base URL is a high-entropy capability, not a user ID. Linkit only stores a hash of it, redacts it from HTTP logs, and exposes it only to its owner through the authenticated settings API. Treat the URL like a device-binding secret: do not share it. Regenerating it removes existing devices and invalidates the old URL; revoking it removes both the URL and all bound devices.

When a message is created, Linkit selects only bound devices of conversation members, skips the human sender, and delivers directly to APNs with its Bark Provider Key. A Bot message can notify every bound conversation member. Clicking a delivered Bark notification opens that message's conversation at Linkit's configured public origin.

Linkit keeps only the minimal Bark iOS lifecycle surface:

GET  /api/bark/b/<private-capability>/ping
GET  /api/bark/b/<private-capability>/register
POST /api/bark/b/<private-capability>/register

The registration request accepts Bark's current device_key/device_token field names and its legacy key/devicetoken names. Sending devicetoken=deleted unbinds the matching device. The APNs Provider Key is a root-owned runtime file, not part of this repository or release archive.

Development

npm --prefix web ci
npm --prefix web run check
npm --prefix web run build
cargo fmt --check
cargo clippy --all-targets --all-features -- -D warnings
cargo test --all-targets --all-features
cargo run

The frontend is built before Rust because web/dist is embedded in the binary.

Release and deployment

main is protected by the pr-check gate. A version tag runs the release workflow, producing Linux x86_64, Linux ARM64, and macOS ARM64 archives with checksums. The Linux x86_64 release is checksum-verified and atomically deployed through AWS Systems Manager to the configured EC2 instance.

Bootstrap a new Ubuntu host with deploy/bootstrap-ubuntu.sh, configure linkit.ntnl.io DNS, obtain its TLS certificate with Certbot, and set repository variables AWS_DEPLOY_ROLE_ARN, AWS_REGION, and EC2_INSTANCE_ID.

Native iOS app

ios/ contains the native SwiftUI client. The Xcode project is generated with XcodeGen from ios/project.yml; see ios/README.md for the feature set, architecture, sign-in flow and CI details.

Design boundary

Root-only administration includes resource monitoring, Bark user visibility and Auth Mini directory synchronization. Setup establishes the authentication boundary. Auth Mini owns sign-in and session issuance; Linkit owns downstream authorization, profiles, conversations, Bot ownership, and message data.

License

MIT

About

Linkit is an Auth Mini-powered profile and instant messaging app.

Resources

Stars

1 star

Watchers

0 watching

Forks

Releases

Packages

Contributors

Languages