Yazma, idempotency ve webhook'lar
This content is not available in your language yet.
Yazma işlemleri
Section titled “Yazma işlemleri”- Her yazma isteği
Idempotency-Keybaşlığı ister (8–64 karakter, ör. UUID). Aynı anahtarla aynı istek 24 saat boyunca aynı yanıtı döner (Idempotent-Replayed: true); aynı anahtarla farklı gövde422, hâlâ sürüyorsa409. - İçerik, HADİ uygulamasındakiyle aynı moderasyondan geçer (küfür, cinsel içerik yasağı, yüz kapısı, EXIF/konum
temizliği, taciz kalkanı, “yalnızca doğrulanmış” modu). İncelemeye düşen gönderi
review: truedöner. - Uygulamanın paylaştığı her gönderi ve yorumda ”🔌 Uygulama adı ile” etiketi görünür; kaldırılamaz.
- Üye başına saatlik sınırlar tüm uygulamalar toplamıdır: yazma 60, takip 30, gönderi 20, yorum 30.
- Fotoğraf:
POST /v1/media/uploadsile 15 dakikalık tek kullanımlık adres al, JPEG’iPUTet, dönenmediaId’yiPOST /v1/postsiçindemediaIdsile kullan. Ücretli etkinliklere API’den katılım şimdilik yok (403 ucretli-etkinlik).
Webhook’lar
Section titled “Webhook’lar”Konsoldan uç nokta eklerken HADİ imzalı bir webhook.test gönderir; 2xx dönmelisin. Olaylar: grant.created,
grant.revoked. Yük incedir — yalnızca tür, kimlik ve zaman; ayrıntıyı API’den (yetki yeniden denetlenerek) çek.
Başlıklar (Standard Webhooks): webhook-id, webhook-timestamp,
webhook-signature: es256,<base64 imza>, webhook-key-id. İmza ES256 (ECDSA P-256 + SHA-256, 64 bayt r ∥ s);
anahtar HADİ’nin donanım güvenlik modülünde (Cloud KMS HSM). İmzalanan metin: `${id}.${timestamp}.${gövde}`.
Açık anahtar: https://auth.hadisosyal.com/jwks.json içinde use: "webhook" olan EC anahtar (kid = webhook-key-id).
Etiket neden
es256? Standard Webhooks’tav1HMAC’e,v1aEd25519’a ayrılmıştır. HADİ ES256 kullandığı için kendi etiketini yazar. Anahtar döndürülürken başlıkta boşlukla ayrılmış birden çok imza olabilir; biri geçerliyse kabul et.
import { createPublicKey, verify } from "node:crypto";
export async function verifyHadiWebhook(headers: Headers, rawBody: string): Promise<boolean> { const id = headers.get("webhook-id"), ts = headers.get("webhook-timestamp"), sig = headers.get("webhook-signature"); if (!id || !ts || !sig) return false; if (Math.abs(Date.now() / 1000 - Number(ts)) > 300) return false; // 5 dk tolerans const { keys } = await (await fetch("https://auth.hadisosyal.com/jwks.json")).json(); // önbelleğe al const jwk = keys.find((k: { use: string; kid: string }) => k.use === "webhook" && k.kid === headers.get("webhook-key-id")); if (!jwk) return false; const key = createPublicKey({ key: { kty: "EC", crv: "P-256", x: jwk.x, y: jwk.y }, format: "jwk" }); const data = Buffer.from(`${id}.${ts}.${rawBody}`); return sig.split(" ").some((p) => p.startsWith("es256,") && verify("sha256", data, { key, dsaEncoding: "ieee-p1363" }, Buffer.from(p.slice(6), "base64")));}webhook-id’yi kaydet ve aynı kimliği ikinci kez işleme (tekrar koruması). Teslim “en az bir kez”dir; başarısız
teslimler 24 saate kadar üstel aralıklarla yeniden denenir, 3 gün kesintisiz hata uç noktayı devre dışı bırakır, 410
yanıtı hemen devre dışı bırakır. Uç nokta herkese açık bir alan adında, https ve 443 portunda olmalı.