ppush

Documentation API

Créez des pushes par script — provisioning, onboarding, CI — tout en conservant le chiffrement de bout en bout.

Authentification

Générez un token personnel dans Compte → Tokens API (affiché une seule fois), puis passez-le en en-tête :

Authorization: Bearer ppush_xxxxxxxxxxxxxxxxxxxx

L'API n'accepte que des contenus déjà chiffrés. Le serveur ne chiffre jamais lui-même — c'est ce qui garantit le zéro-knowledge. Utilisez le CLI fourni (recommandé) ou implémentez le format ci-dessous.

Le CLI (recommandé)

tools/ppush-cli.mjs (dans le dépôt) chiffre localement puis appelle l'API. Node ≥ 20, aucune dépendance.

export PPUSH_URL=http://localhost:3000
export PPUSH_TOKEN=ppush_xxx

# mot de passe, 3 vues max, 7 jours
ppush-cli.mjs --password "S3cret!" --views 3 --days 7

# texte depuis stdin
cat config.yml | ppush-cli.mjs --text -

# fichier avec passphrase et note privée
ppush-cli.mjs --file dump.sql.gz --passphrase "sesame" --note "backup pour Bob"

# → imprime l'URL complète, clé de déchiffrement incluse dans le fragment

Options : --days N · --views N · --passphrase X · --note "…" · --no-retrieval-step · --no-deletable

Endpoints

POST/api/pushesBearer ou session

Crée un push. Corps JSON :

{
  "kind": "PASSWORD" | "TEXT" | "FILE" | "URL",
  "ciphertext": "<base64>",          // payload chiffré (cf. format)
  "blobPath": "xxx.bin",             // FILE uniquement (cf. POST /api/blobs)
  "passphrase": "optionnelle",
  "expireAfterDays": 7,              // 1..30
  "expireAfterViews": 5,             // 1..50
  "retrievalStep": true,
  "deletableByViewer": true,
  "note": "référence privée optionnelle"
}

Réponse 201 : { "slug", "url", "expiresAt", … }. Le lien à transmettre est url + "#" + clé_base64url— la clé n'est connue que de vous.

POST/api/blobsBearer ou session

Upload du blob chiffré d'un fichier (corps brut, max ~100 Mo avec un compte). Réponse : { "blobPath": "xxx.bin", "size": 123 } à passer ensuite à POST /api/pushes.

GET/api/pushes?page=1&filter=activeBearer ou session

Liste paginée de vos pushes. filter : active | expired | (omis = tous).

GET/api/pushes/:slugBearer ou session

Détail d'un push + journal d'audit complet (events : CREATED, VIEW, FAILED_PASSPHRASE, EXPIRED, OWNER_DELETE, VIEWER_DELETE, avec IP et user-agent).

DELETE/api/pushes/:slugBearer ou session

Fait expirer le push immédiatement (purge définitive du payload).

GET/api/p/:slugpublic

Métadonnées publiques d'un push (type, expiré ou non, passphrase requise…). Ne consomme pas de vue.

POST/api/p/:slug/revealpublic

Révèle le ciphertext et consomme une vue. Corps : { "passphrase": "…" } si exigée. Pour un FILE, retourne aussi un viewToken à usage unique pour GET /api/p/:slug/blob?vt=….

POST/api/p/:slug/burnpublic

Destruction par le destinataire (si autorisée à la création).

Format de chiffrement (v1)

Si vous n'utilisez pas le CLI, produisez le ciphertext ainsi (AES-256-GCM, WebCrypto ou équivalent) :

Clé      : 32 octets aléatoires → base64url → fragment du lien (#…)
Payload  : JSON { "t": "PASSWORD|TEXT|URL", "d": "<secret>" }
           (FILE : { "t":"FILE", "d":"", "name", "mime", "size" })

ciphertext = 0x01 ‖ IV(12 octets) ‖ AES-256-GCM(payload, AAD="ppush:v1:meta")
           → base64 dans le champ "ciphertext"

Fichiers (blob) : chunks de 8 Mio, chacun encadré :
  [longueur u32 BE] [IV 12 octets] [ct+tag]
  AAD du chunk i : "ppush:v1:<i>:<1 si dernier, sinon 0>"

Limites & erreurs

  • Réponses d'erreur : { "error": "message" } avec le statut HTTP approprié (400 validation, 401 auth, 403 interdit, 404 introuvable, 409 conflit, 410 expiré, 413 trop volumineux, 429 rate limit).
  • Rate limiting par IP sur les endpoints sensibles (login, passphrase, reveal). En cas de 429, attendez puis réessayez.
  • Payload texte chiffré : 1024 Ko max · fichiers : 100 Mo max (compte) · rétention : 30 jours / 50 vues max. Sans compte : 7 jours / 5 vues, fichiers 10 Mo.
  • Un token API a les droits de son propriétaire (création, listing, expiration de ses pushes). Révocable à tout moment depuis le compte.

Voir aussi la page À propos et la gestion des tokens.