OverviewFilesCommitsIssuesDocsReleasesPeers

keet-deobfuscated / @holepunchto / keet-core / lib / push / index.js

218 lines · javascript ref:
const e = require("hypercore-id-encoding"),
  l = require("hypercore-storage"),
  t = require("multi-profile-store"),
  a = require("@holepunchto/keet-push/lib/notifications.js"),
  { decodeValue: o } = require("autobase/lib/values.js"),
  n = require("b4a"),
  {
    contract: {
      hyperdispatch: { decode: i },
      hyperschema: { getEnum: r },
    },
  } = require("../../schema/spec"),
  c = r("@keet/room-type"),
  s = require("../core/local"),
  u = require("keet-identity-key"),
  { ProofEncoding: d } = require("keet-identity-key/lib/encoding"),
  m = require("compact-encoding")
function y(e) {
  return "@keet/start-call" === e.name
    ? "call"
    : "@keet/join-call" === e.name
      ? "call_joined"
      : "@keet/end-call" === e.name || "@keet/leave-call" === e.name
        ? "call_hangup"
        : void 0
}
function f(e) {
  return "@keet/start-call" === e.name
    ? "Message for call"
    : "@keet/join-call" === e.name
      ? "Message for call joined"
      : "@keet/end-call" === e.name || "@keet/leave-call" === e.name
        ? "Message for call hangup"
        : void 0
}
function p(e, l) {
  switch (e) {
    case c.Default:
      return (l("Room type is default"), "0")
    case c.Broadcast:
      return (l("Room type is Broadcast"), "1")
    case c.DirectMessage:
      return (l("Room type is DirectMessage"), "2")
    default:
      throw new Error("Incompatible legacy room type:", e)
  }
}
function g(e, l, t) {
  try {
    return !!u.verify(e, l, { expectedIdentity: t })
  } catch {
    return !1
  }
}
module.exports = async function (r, c, { log: u = () => {}, profile: k = !0 } = {}) {
  const h = t.open(r).active()
  if (!h && k) return (u("no active profile is made"), null)
  const { version: v, discoveryKey: b, proof: x } = a.decode(c),
    K = new l(h ? h.storage : r, {
      readOnly: !0,
      blockCache: !1,
      tableCacheIndexAndFilterBlocks: !1,
      optimizeFiltersForMemory: !0,
      maxOpenFiles: 1,
      useDirectReads: !0,
      filterPolicy: null,
    })
  try {
    const l = s.rocks(K.rocks.columnFamily("keet/local-database"))
    ;(await l.ready(), u("Keet local database is ready"))
    const [t, r] = await Promise.all([
      l.get("@local/rooms-by-discovery-key", { discoveryKey: b }),
      l.get("@local/identity"),
    ])
    if (!t || t.status.isRemoved) return (u("Room member was removed from room"), null)
    const c = await l.get("@local/room-preferences", { roomKey: t.roomKey })
    if (c && (!c.status.isActive || c.status.isFullyMuted)) return null
    const k = await a.receive(K, t.roomKey, x, v),
      h = 1 === v ? k?.result : k,
      w = 1 === v ? k?.attest : null,
      M = w ? m.decode(d, w) : null
    if ((u("Receiving notification"), !h)) return null
    if ((u("Notification is good"), !h.block)) return null
    if ((u("Notification was not blocked"), !h.newer)) return null
    const q = h.key,
      T = h.discoveryKey,
      I = o(n.from(h.proof.block.value), {
        autobase: t.roomKey,
        encryptionKey: t.encryptionKey,
        key: q,
        manifest: h.proof.manifest,
        index: h.block.index,
      }),
      [R, j] = await Promise.all([l.get("@local/devices", { device: { key: q } }), I]),
      D = R?.device,
      F = i(j),
      B = M?.identity || D?.memberKey,
      [P, A] = await Promise.all([
        B ? l.get("@local/contacts", { memberKey: B }) : null,
        B ? l.get("@local/members", { key: B }) : null,
      ]),
      E = !!P?.status.isBlocked
    u("Blocked?: ", E)
    const S = w ? g(w, q, r.publicKey) : A && n.equals(A.key, r.publicKey)
    u(
      `Member exists ?: ${null !== A} and keys are equal?: ${null !== A && n.equals(A.key, r.publicKey)}`,
    )
    const N = A ? A.profile.displayName : null,
      _ = A ? A.profile.avatar : null,
      C = t ? t.config.avatar : null,
      O = t ? t.digest.abi.version : 0
    let $ = null
    switch (F.name) {
      case "@keet/add-chat-message": {
        const l = F.value.header.timestamp,
          a = F.value.message
        if (a?.files && a.files.length > 0) {
          const e = a.files[0]
          ;(($ = {
            timestamp: l,
            type: "file",
            chatText: null,
            callId: null,
            fileType: e.metadata?.mimetype,
            location: null,
          }),
            u("Message for file"))
        } else if (a?.event?.locationShared)
          (($ = {
            timestamp: l,
            type: "location",
            chatText: a.text,
            callId: null,
            fileType: null,
            location: a.event.locationShared,
          }),
            u("Message for location"))
        else if (a.text)
          (($ = {
            timestamp: l,
            type: "text",
            chatText: a.text,
            callId: null,
            fileType: null,
            location: null,
          }),
            u("Message for text"))
        else if (a.event.callStarted && O < 23) {
          if (Math.abs(Date.now() - l) > 12e4) return
          ;(($ = {
            timestamp: l,
            type: "call",
            chatText: null,
            callId: e.encode(t.discoveryKey),
            fileType: null,
            location: null,
          }),
            u("Message for call"))
        } else if (a.event.callHangup && O < 23) {
          if (Math.abs(Date.now() - l) > 12e4) return
          ;(($ = {
            timestamp: l,
            type: "call_hangup",
            chatText: null,
            callId: e.encode(t.discoveryKey),
            fileType: null,
            location: null,
          }),
            u("Message for call hangup"))
        }
        break
      }
      case "@keet/start-call":
      case "@keet/join-call":
      case "@keet/leave-call":
      case "@keet/end-call": {
        if (O < 23) return
        const l = F.value.header.timestamp
        if (Math.abs(Date.now() - l) > 12e4) return
        const t = y(F),
          a = f(F)
        ;(($ = {
          timestamp: l,
          type: t,
          chatText: null,
          callId: e.encode(F.value.callKey),
          fileType: null,
          location: null,
        }),
          u(a))
        break
      }
    }
    const z = {
      id: null,
      sender: { id: e.encode(q), length: h.length, blocked: E, self: S, name: N, memberAvatar: _ },
      room: {
        key: t.roomKey,
        title: t.config.title,
        type: p(t.digest.settings.roomType, u),
        roomAvatar: C,
      },
      proof: { discoveryKey: T, data: h.proof },
      index: h.block.index,
      message: $,
    }
    return (
      (z.id = z.sender.id + (-1 !== z.index ? "/b" + z.index : "/l" + z.sender.length)),
      u("Returning result"),
      z
    )
  } catch (e) {
    return (u("Error:", e), null)
  } finally {
    ;(await K.close(), u("Storage closed"))
  }
}