sipher/package.json
Nixyan 660c17b319 feat: add client-side identity system, rate limiting, proxy hardening, and full test suite
### Major changes

- **Client-side identity** — New session key store (`sessionKey.ts`) backed by
  `sessionStorage` with a module-level caching, a `crypto.subtle` cache, a `useIdentityLock`
  hook for decrypt-once signing, `followSignature.ts` for signed follows, and
  two new UI modals (`IdentityBackup.tsx`, `UnlockIdentityModal.tsx`).
  `CreateIdentity.tsx` is rewritten to generate BIP-39 mnemonics and encrypt the
  Ed25519 keypair with AES-256-GCM via PBKDF2 (600k iterations) before storing
  in IndexedDB.

- **Rate limiting** — New `rate-limit-config.ts` and `rate-limit.ts` provide a
  per-IP sliding-window rate limiter backed by Redis. All external-facing routes
  (`/discover`, `/discover/rotate/*`, `/proxy`, social API endpoints) now have
  conservative defaults wired into the custom HTTP server before requests reach
  Next.js handlers.

- **Proxy route hardening** — The `/proxy` route now enforces a 256 KB payload
  limit (HTTP 413), validates JSON before parsing, applies a per-origin rate
  limit (100 req/min), and imports the `blocks` table to reject requests from
  blocked servers.

- **Docker integration-test cluster** — New `Dockerfile`, `.dockerignore`, and
  `tests/docker-compose.yml` orchestrate three SiPher instances (A, B, C) plus
  shared PostgreSQL and Redis. Key generation (`generate-keys.ts`) and discovery
  setup (`setup-discovery.ts`) scripts automate cluster bootstrap. Three example
  env files document required per-instance configuration.

- **Full test suite overhaul** — Replaces the old attack/auth/discover/key/proxy
  tests with a structured suite:
  * `tests/federation/` — Keytools unit tests + key-rotation e2e test
  * `tests/proxy/` — Proxy relay e2e tests (single-server validation)
  * `tests/integration/` — Multi-instance integration tests for discover,
    proxy-chain relay, and federated post delivery via BullMQ
  * `tests/helpers/` — Reusable DB, identity, and auth-user utilities
  * Playwright config updated to match new file conventions
  * Unused helpers (`tests/helpers/queue.ts`) removed

- **Social plugin endpoints** — Rewritten `follows.ts`, `blocks.ts`, `mutes.ts`,
  and `posts.ts` with proper federation integration. `social.ts` gains helpers
  for looking up posts by federation URL.

### Minor changes

- **README** — Expanded from a 42-line stub to a full architecture guide with
  tables for every layer (auth, DB, queues, storage, real-time), API route
  documentation, setup instructions, environment variables, test coverage, and
  the updated roadmap.

- **Federation helpers** — `keytools.ts` refactors imports and cleans up the public surface.
  `fetch.ts`, `registry.ts`, and `proxy-helpers/federated-post.ts` pick up small
  improvements. `PostFederationSchema` simplifies its encryption type assertion.

- **Plugin infrastructure** — Oven plugin schema and server index gain minor
  refactors. Social client adds a `muteUser` method.

- **UI components** — `switch.tsx` and `tooltip.tsx` rewritten for Radix v2 /
  Tailwind 4; `accordion.tsx`, `dropdown-menu.tsx`, `form`, `button`, `card` get
  minor consistency fixes. `dialog.tsx` removes unused `DialogHeader`.

- **Server bootstrap** — `server.ts` imports DB schema before `instrumentation`
  for correct Drizzle initialization, rate-limiting routes are wired, and CORS
  allows federation origins. `auth.ts` regenerates Oven and social plugin schemas.

- **Dependencies** — Added `@noble/ciphers` and `@noble/hashes` (crypto
  primitives). Removed `@signalapp/libsignal-client`, `base58-js`, `nanostores`,
  `tweetnacl-util`, `dexie-react-hooks`, `socket.io-client`. Updated all Better
  Auth packages to 1.6.11, BullMQ to 5.76.10, and various dev deps across the
  board.

- **.gitignore** — Added `/audits` and `tests/docker/*.env` to prevent secret
  leakage.

- **DB schema** — `blocks` table imported in `src/lib/db/schema/index.ts`.

Co-authored-by: Cursor <cursoragent@cursor.com>
2026-05-18 09:48:42 -03:00

121 lines
No EOL
4.4 KiB
JSON

{
"name": "silent-whisper",
"description": "A federated social media platform for the modern age.",
"author": [
{
"name": "Marcello Brito",
"alias": "Tocka",
"email": "tocka@tockanest.com",
"url": "https://tockanest.com"
}
],
"license": "AGPL-3.0",
"version": "0.2.0",
"private": true,
"scripts": {
"dev": "cross-env NODE_ENV=development FEDERATION_ALLOW_PRIVATE_URLS=true tsx src/server.ts",
"email:dev": "cross-env NODE_ENV=development email dev --dir src/lib/mail/templates --port 3001",
"test": "cross-env NODE_ENV=test playwright test",
"test:integration:post": "cross-env NODE_ENV=test bun run tests/integration/federation-post-delivery.ts",
"test:integration:proxy-chain": "cross-env NODE_ENV=test bun run tests/integration/proxy-chain.ts",
"keygen": "bun run src/lib/federation/keygen.ts",
"docker:generate-keys": "bun run tests/docker/generate-keys.ts",
"docker:setup-discovery": "docker compose -f tests/docker-compose.yml run --rm setup-discovery",
"docker:build": "docker compose -f tests/docker-compose.yml --profile init --profile setup --profile test build",
"docker:up": "docker compose -f tests/docker-compose.yml up -d",
"docker:down": "docker compose -f tests/docker-compose.yml down",
"docker:init": "docker compose -f tests/docker-compose.yml --profile init up",
"docker:test:proxy-chain": "docker compose -f tests/docker-compose.yml run --rm test-runner tests/integration/proxy-chain.ts --proxy http://sipher-b:3001 --target http://sipher-c:3002",
"docker:test:post-delivery": "docker compose -f tests/docker-compose.yml run --rm test-runner tests/integration/federation-post-delivery.ts --proxy http://sipher-b:3001 --target http://sipher-c:3002",
"docker:test:discover": "docker compose -f tests/docker-compose.yml run --rm test-runner tests/integration/discover.ts --peer http://sipher-c:3002",
"test:key": "cross-env NODE_ENV=test playwright test tests/federation/key-rotation.e2e.ts",
"test:federation": "cross-env NODE_ENV=test playwright test tests/federation",
"test:proxy": "cross-env NODE_ENV=test playwright test tests/proxy",
"build": "next build",
"build:matrix": "cd node_modules/@matrix-org/matrix-sdk-crypto-nodejs && node download-lib.js",
"start": "cross-env NODE_ENV=production node src/server.ts",
"db:push": "drizzle-kit push",
"db:migrate": "bun run db:push && bun run drizzle-kit migrate",
"db:generate": "auth generate --output src/lib/db/schema/index.ts --yes",
"db:update": "bun run db:generate && bun run db:push"
},
"dependencies": {
"@better-auth/drizzle-adapter": "^1.6.11",
"@hookform/resolvers": "^5.2.2",
"@matrix-org/matrix-sdk-crypto-wasm": "^18.3.0",
"@noble/ciphers": "^2.2.0",
"@noble/hashes": "^2.2.0",
"@react-email/components": "1.0.12",
"@react-email/render": "^2.0.8",
"@react-email/tailwind": "^2.0.7",
"@scure/bip39": "^2.2.0",
"better-auth": "^1.6.11",
"bullmq": "^5.76.10",
"class-variance-authority": "^0.7.1",
"clsx": "^2.1.1",
"debug": "^4.4.3",
"dexie": "^4.4.2",
"dotenv": "^17.4.2",
"drizzle-orm": "^0.45.2",
"framer-motion": "^12.38.0",
"ioredis": "^5.10.1",
"lucide-react": "^1.16.0",
"minio": "^8.0.7",
"next": "16.2.3",
"next-themes": "^0.4.6",
"nodemailer": "^8.0.7",
"pg": "^8.21.0",
"radix-ui": "^1.4.3",
"react": "19.2.5",
"react-dom": "19.2.5",
"react-hook-form": "^7.76.0",
"socket.io": "^4.8.3",
"sonner": "^2.0.7",
"tailwind-merge": "^3.6.0",
"tweetnacl": "^1.0.3",
"uuid": "^14.0.0",
"zod": "^4.4.3"
},
"devDependencies": {
"@playwright/test": "^1.60.0",
"@react-email/preview-server": "^5.2.10",
"@tailwindcss/postcss": "^4.3.0",
"@types/bun": "^1.3.14",
"@types/debug": "^4.1.13",
"@types/node": "^25.8.0",
"@types/nodemailer": "^8.0.0",
"@types/pg": "^8.20.0",
"@types/react": "^19.2.14",
"@types/react-dom": "^19.2.3",
"auth": "^1.6.11",
"babel-plugin-react-compiler": "1.0.0",
"cross-env": "^10.1.0",
"drizzle-kit": "^0.31.10",
"react-email": "5.2.10",
"shadcn": "^4.7.0",
"tailwindcss": "^4.3.0",
"tsx": "^4.22.1",
"tw-animate-css": "^1.4.0",
"typescript": "^6.0.3"
},
"ignoreScripts": [
"sharp",
"unrs-resolver"
],
"trustedDependencies": [
"sharp",
"unrs-resolver"
],
"repository": {
"type": "git",
"url": "https://github.com/tockawaffle/sipher.git"
},
"bugs": {
"url": "https://github.com/tockawaffle/sipher/issues"
},
"keywords": [
"social",
"media",
"federated"
]
}