rooms-kit / src / ardegazu / rooms / lib / orbit_identity.cljs
 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
;; ported-from: src/lib/orbit-identity.ts @ v1.0.0
;;
;; OrbitDB identity provider backed by the persistent Ed25519 seed identity. Log
;; entries chain to the durable identity: the provider id IS the base64url public
;; key peers already TOFU/verify in the roster, so authorship in the replicated
;; log and live presence share one identity.
;;
;; Wire format (OrbitDB contract, verified against @orbitdb/core 3.x source): the
;; device keystore's secp256k1 key signs each entry; the provider links it to the
;; durable key by signing the string `publicKey + signatures.id`. With
;; replication encryption ON, identities and signatures live inside ciphertext —
;; visible to room members only (PROTOCOL.md §7b preserved).
;;
;; VENDOR RETIREMENT: `verifyRaw` comes from the real id-kit — now as the
;; defining namespace `ardegazu.id.identity`, compiled from the sha-pinned
;; sources on this build's classpath (the arrangement peer-kit and social-kit
;; also use) rather than imported from its dist. v1.0.0 used a hand-maintained
;; TypeScript copy under src/vendor/id/.
(ns ardegazu.rooms.lib.orbit-identity
  (:require ["@orbitdb/core" :as orbit]
            [ardegazu.id.identity :as id]
            [ardegazu.rooms.js :as j]
            [ardegazu.rooms.lib.crypto :as rc]
            [shadow.cljs.modern :refer (js-await)]))

(def ^:private te (js/TextEncoder.))

(defn SuetaIdentityProvider [opts]
  (let [identity (unchecked-get opts "identity")]
    (fn []
      (js/Promise.resolve
       (j/ordered
        "type" "sueta"
        "getId" (fn [] (js/Promise.resolve (unchecked-get identity "publicKeyB64")))
        "signIdentity" (fn [data]
                         (js-await [sig (.signRaw ^js identity (.encode te data))]
                           (rc/to-b64url sig))))))))

(unchecked-set SuetaIdentityProvider "type" "sueta")
(unchecked-set SuetaIdentityProvider "verifyIdentity"
               (fn [identity]
                 (id/verify-raw (unchecked-get identity "id")
                                (unchecked-get (unchecked-get identity "signatures") "publicKey")
                                ;; JS `+` on the two strings — `str` would turn an
                                ;; absent field into "" where JS gives "undefined"
                                (.encode te (js* "~{} + ~{}"
                                                 (unchecked-get identity "publicKey")
                                                 (unchecked-get (unchecked-get identity "signatures") "id"))))))

(defonce ^:private registered (atom false))

(defn register-sueta-provider
  "Idempotent registration with OrbitDB's provider registry."
  []
  (when-not @registered
    (reset! registered true)
    (orbit/useIdentityProvider SuetaIdentityProvider))
  js/undefined)

static mirror of HEAD · about · clone: git clone https://git.ardegazu.ro/rooms-kit.git