Files
p2ns/plugin-sites/peer.paste
2026-05-30 23:38:56 -04:00
..
2026-05-30 21:01:31 -04:00
2026-05-30 17:21:25 -04:00
2026-05-30 23:38:56 -04:00
2026-05-28 01:10:11 -04:00

peer.paste

Temporary P2P text snippets for the P2NS network.

Features

  • Realtime websocket-driven UI updates
  • Text and markdown authoring with live preview
  • Syntax highlighting support in preview and paste views
  • Encryption by default (AES-GCM), optional public mode
  • Optional passphrase-derived encryption mode
  • Expiring pastes (default 24h, max 7 days)
  • Optional burn-after-first-read and max-read limits
  • Lightweight inline attachments with total-size cap
  • Public share links (/p/:id)
  • Raw consume API (/api/pastes/:id/raw)
  • Metadata replication via HyperDB

API

  • POST /api/pastes create paste
  • GET /api/pastes list active pastes
  • GET /api/pastes/mine list active pastes owned by local peer
  • GET /api/pastes/:id metadata
  • GET /api/pastes/:id/raw consume/read paste content
  • GET /api/pastes/:id/attachments list attachment metadata
  • GET /api/pastes/:id/attachments/:attachmentId get attachment payload
  • PUT /api/pastes/:id update paste (owner only, authenticated)
  • DELETE /api/pastes/:id delete paste (owner only, authenticated)
  • GET /api/stats service stats
  • GET /api/health service health
  • POST /api/admin/cleanup trigger immediate cleanup (authenticated)
  • GET /api/docs interactive API docs page
  • GET /api/openapi.json machine-readable OpenAPI schema
  • GET /p/:id human-readable paste page

curl examples

Replace https://peer.paste with your nodes plugin URL. If you use the local P2NS TLS cert, add -k to skip verification.

Create a public paste

Public pastes store plaintext on the server (no browser encryption step), which is easiest for API clients:

curl -sS -X POST 'https://peer.paste/api/pastes' \
  -H 'Content-Type: application/json' \
  -d '{
    "public": true,
    "content": "Hello from curl",
    "format": "text",
    "language": "plaintext",
    "expiresHours": 24
  }'

Example response (fields may vary):

{
  "success": true,
  "paste": { "id": "abc123...", "format": "text", "isPublic": true, ... },
  "viewUrl": "/p/abc123...",
  "apiUrl": "/api/pastes/abc123...",
  "rawUrl": "/api/pastes/abc123.../raw"
}

Save paste.id (or parse it with jq):

PASTE_ID=$(curl -sS -X POST 'https://peer.paste/api/pastes' \
  -H 'Content-Type: application/json' \
  -d '{"public":true,"content":"Quick test","format":"text"}' \
  | jq -r '.paste.id')
echo "$PASTE_ID"

Markdown example:

curl -sS -X POST 'https://peer.paste/api/pastes' \
  -H 'Content-Type: application/json' \
  -d '{
    "public": true,
    "content": "# Title\n\nSome **markdown**.",
    "format": "markdown",
    "language": "markdown"
  }'

Encrypted pastes require a client-generated encrypted payload (iv, ciphertext, optional salt); use the web UI or your own crypto before calling POST /api/pastes without "public": true.

View a paste

Metadata (does not increment read count):

curl -sS "https://peer.paste/api/pastes/${PASTE_ID}"

Raw content (increments readCount; may delete burn-after-read pastes):

curl -sS "https://peer.paste/api/pastes/${PASTE_ID}/raw"

For a public paste, the JSON includes paste.content. For encrypted pastes, use paste.encryptedPayload and decrypt in your client, or open the share link in a browser with the #k=... key fragment.

Browser page (HTML UI, decrypt UI for encrypted pastes):

https://peer.paste/p/${PASTE_ID}

Pretty-print raw JSON:

curl -sS "https://peer.paste/api/pastes/${PASTE_ID}/raw" | jq .

Realtime WebSocket Messages

  • Client -> server: request-pastes, create-paste, destroy-paste
  • Server -> client: init, pastes-page, pastes-updated, paste-created, paste-destroyed, error

Payload Notes

  • Create/Update fields used by plugin:
    • format: text or markdown
    • public: true for plaintext storage, otherwise encrypted payload expected
    • encrypted: { iv, ciphertext, salt? } for encrypted mode
    • encryptionMode: e.g. aes-gcm, passphrase-aes-gcm, none
    • attachments: inline list of { id, name, mime, size, data }

Limits and Behavior

  • Content max length: 100000 chars
  • Expiry max: 168 hours
  • Max read count value: 1000000
  • Attachment cap:
    • max attachments processed: 16
    • max total attachment bytes: 64MB
  • The realtime sidebar lists all active pastes in the replicated database (every peer), not only local ones. Burn-after-read pastes are excluded from that feed.
  • Cleanup task runs hourly and removes expired/consumed entries.
  • Paste data is replicated via HyperDB.

Local Vendor Assets (No CDN)

peer.paste serves markdown/highlight dependencies locally via:

  • /api/vendor/marked.min.js
  • /api/vendor/highlight.min.js
  • /api/vendor/highlight-dark.css

Validation Script

  • Run node test-scripts/peer-paste-smoke.js https://peer.paste to validate core API/OpenAPI availability.