OverviewFilesCommitsIssuesDocsReleasesPeers

keet-cli / keet-core-4.14.4-pretty / lib / push / index.js

214 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")
function d(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 m(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 y(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 f(e, l, t) {
  try {
    return !!u.verify(e, l, { expectedIdentity: t })
  } catch {
    return !1
  }
}
module.exports = async function (r, c, { log: u = () => {}, profile: p = !0 } = {}) {
  const g = t.open(r).active()
  if (!g && p) return (u("no active profile is made"), null)
  const { version: k, discoveryKey: h, proof: v } = a.decode(c),
    b = new l(g ? g.storage : r, {
      readOnly: !0,
      blockCache: !1,
      tableCacheIndexAndFilterBlocks: !1,
      optimizeFiltersForMemory: !0,
      maxOpenFiles: 1,
      useDirectReads: !0,
      filterPolicy: null,
    })
  try {
    const l = s.rocks(b.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: h }),
      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 p = await a.receive(b, t.roomKey, v, k),
      g = 1 === k ? p?.result : p,
      x = 1 === k ? p?.attest : null
    if ((u("Receiving notification"), !g)) return null
    if ((u("Notification is good"), !g.block)) return null
    if ((u("Notification was not blocked"), !g.newer)) return null
    const K = g.key,
      w = g.discoveryKey,
      M = o(n.from(g.proof.block.value), {
        autobase: t.roomKey,
        encryptionKey: t.encryptionKey,
        key: K,
        manifest: g.proof.manifest,
        index: g.block.index,
      }),
      [T, q] = await Promise.all([l.get("@local/devices", { device: { key: K } }), M]),
      I = T?.device,
      R = i(q),
      [j, D] = await Promise.all([
        I ? l.get("@local/contacts", { memberKey: I.memberKey }) : null,
        I ? l.get("@local/members", { key: I.memberKey }) : null,
      ]),
      F = !!j?.status.isBlocked
    u("Blocked?: ", F)
    const B = x ? f(x, K, r.publicKey) : D && n.equals(D.key, r.publicKey)
    u(
      `Member exists ?: ${null !== D} and keys are equal?: ${null !== D && n.equals(D.key, r.publicKey)}`,
    )
    const A = D ? D.profile.displayName : null,
      P = D ? D.profile.avatar : null,
      S = t ? t.config.avatar : null,
      E = t ? t.digest.abi.version : 0
    let N = null
    switch (R.name) {
      case "@keet/add-chat-message": {
        const l = R.value.header.timestamp,
          a = R.value.message
        if (a?.files && a.files.length > 0) {
          const e = a.files[0]
          ;((N = {
            timestamp: l,
            type: "file",
            chatText: null,
            callId: null,
            fileType: e.metadata?.mimetype,
            location: null,
          }),
            u("Message for file"))
        } else if (a?.event?.locationShared)
          ((N = {
            timestamp: l,
            type: "location",
            chatText: a.text,
            callId: null,
            fileType: null,
            location: a.event.locationShared,
          }),
            u("Message for location"))
        else if (a.text)
          ((N = {
            timestamp: l,
            type: "text",
            chatText: a.text,
            callId: null,
            fileType: null,
            location: null,
          }),
            u("Message for text"))
        else if (a.event.callStarted && E < 23) {
          if (Math.abs(Date.now() - l) > 12e4) return
          ;((N = {
            timestamp: l,
            type: "call",
            chatText: null,
            callId: e.encode(t.discoveryKey),
            fileType: null,
            location: null,
          }),
            u("Message for call"))
        } else if (a.event.callHangup && E < 23) {
          if (Math.abs(Date.now() - l) > 12e4) return
          ;((N = {
            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 (E < 23) return
        const l = R.value.header.timestamp
        if (Math.abs(Date.now() - l) > 12e4) return
        const t = d(R),
          a = m(R)
        ;((N = {
          timestamp: l,
          type: t,
          chatText: null,
          callId: e.encode(R.value.callKey),
          fileType: null,
          location: null,
        }),
          u(a))
        break
      }
    }
    const _ = {
      id: null,
      sender: { id: e.encode(K), length: g.length, blocked: F, self: B, name: A, memberAvatar: P },
      room: {
        key: t.roomKey,
        title: t.config.title,
        type: y(t.digest.settings.roomType, u),
        roomAvatar: S,
      },
      proof: { discoveryKey: w, data: g.proof },
      index: g.block.index,
      message: N,
    }
    return (
      (_.id = _.sender.id + (-1 !== _.index ? "/b" + _.index : "/l" + _.sender.length)),
      u("Returning result"),
      _
    )
  } catch (e) {
    return (u("Error:", e), null)
  } finally {
    ;(await b.close(), u("Storage closed"))
  }
}