(ns ird.p2p
"P2P apps: signalling/relay infrastructure with TURN credentials, an
offline mailbox, origin control and custom domains. Every function returns
a channel (see ird.async)."
(:require [ird.async :refer [go-try <?]]
[ird.gate :as gate]
[ird.transport :as transport]))
(defn list-apps
"GET /p2p/apps — List your p2p apps."
[client]
(transport/request client :get "/p2p/apps"))
(defn create-app
"POST /p2p/apps — Create a p2p app.
BODY keys include :name, :origins, :settings and :mailbox_enabled (the
offline mailbox is off by default)."
[client body]
(transport/request client :post "/p2p/apps" {:body body}))
(defn get-app
"GET /p2p/apps/{id} — P2P app detail."
[client id]
(transport/request client :get ["p2p" "apps" id]))
(defn delete-app
"DELETE /p2p/apps/{id} — Delete a p2p app."
[client id]
(transport/request client :delete ["p2p" "apps" id]))
(defn update-app
"PATCH /p2p/apps/{id} — Update app origins/settings/relay/mailbox.
BODY keys include :origins, :settings, :relay_enabled, :mailbox_enabled
and :mailbox_open_mint (turn open minting off to hand out mailbox tokens
only from your own backend via `mint-mailbox-credentials`). Each provided
key is a full replace; omitted keys are left untouched."
[client id body]
(transport/request client :patch ["p2p" "apps" id] {:body body}))
(defn mint-turn-credentials
"POST /p2p/apps/{id}/turn-credentials — Mint TURN credentials.
Optional BODY carries :ttl_sec."
([client id] (mint-turn-credentials client id nil))
([client id body]
(transport/request client :post ["p2p" "apps" id "turn-credentials"] (when body {:body body}))))
(defn mint-mailbox-credentials
"POST /p2p/apps/{id}/mailbox-credentials — Mint a short-lived bearer token
for the app's offline mailbox (requires :mailbox_enabled on the app).
Optional BODY carries :room (scope the token to one rendezvous id; omit
for an app-wide token) and :ttl_sec (default 3600, capped at 86400).
The response's :credentials carry the :token and the :endpoint
(`https://<hostname>/mailbox/v1`) — see ird.mailbox for that data plane."
([client id] (mint-mailbox-credentials client id nil))
([client id body]
(transport/request client :post ["p2p" "apps" id "mailbox-credentials"] (when body {:body body}))))
(defn list-app-domains
"GET /p2p/apps/{id}/domains — List an app's custom domains."
[client id]
(transport/request client :get ["p2p" "apps" id "domains"]))
(defn attach-domain
"POST /p2p/apps/{id}/domains — Attach a custom domain.
BODY keys include :hostname and optional :wildcard. Subject to the
client's domain gate on :hostname."
[client id body]
(gate/request client "POST /p2p/apps/{id}/domains" {:domain (:hostname body)}
:post ["p2p" "apps" id "domains"] {:body body}))
(defn- app-domain-target
"Gate target for a custom domain: its hostname, found in
`list-app-domains`. Called only when the client has a gate."
[client id domain-id]
(go-try
{:domain (some #(when (= (str domain-id) (str (:id %))) (:hostname %))
(:domains (<? (list-app-domains client id))))}))
(defn detach-domain
"DELETE /p2p/apps/{id}/domains/{domain-id} — Detach a custom domain.
Subject to the client's domain gate on the domain's hostname (resolved
via `list-app-domains` when a gate is set)."
[client id domain-id]
(gate/request client "DELETE /p2p/apps/{id}/domains/{domain-id}"
#(app-domain-target client id domain-id)
:delete ["p2p" "apps" id "domains" domain-id]))
(defn verify-domain-dns
"POST /p2p/apps/{id}/domains/{domain-id}/verify-dns — Re-check a domain's
DNS."
[client id domain-id]
(transport/request client :post ["p2p" "apps" id "domains" domain-id "verify-dns"]))
(defn usage
"GET /p2p/usage — P2P usage and cost."
[client]
(transport/request client :get "/p2p/usage"))