OverviewFilesCommitsIssuesDocsReleasesPeers

keet-cli / keet-core-4.14.4-pretty / lib / core / contract / internal.js

165 lines · javascript ref:
const e = require("b4a"),
  t = require("./registration"),
  { KeetContractError: i } = require("./errors"),
  { isMemberActive: s, getMemberForDeviceKey: a } = require("./query"),
  { addDevice: r, addMember: n } = require("./members"),
  {
    contract: {
      hyperschema: { getEnum: o },
    },
  } = require("../../../schema/spec"),
  d = o("@keet/room-type"),
  c = o("@keet/build-type"),
  m = [
    "roomType",
    "isExperimental",
    "isJoiningDisabled",
    "isAppendingDisabled",
    "isCallingDisabled",
    "isMembershipEventsDisabled",
    "isAttachmentsDisabled",
    "isLinksDisabled",
  ],
  u = {
    RoomType: 1,
    IsExperimental: 2,
    IsJoiningDisabled: 3,
    IsAppendingDisabled: 4,
    IsCallingDisabled: 5,
    IsMembershipEventsDisabled: 6,
    IsAttachmentsDisabled: 7,
    IsLinksDisabled: 8,
  }
async function l(
  {
    header: t,
    digest: s,
    config: o,
    capabilities: c,
    identity: m,
    bootstrapDevice: u,
    initialMembers: l,
  },
  p,
) {
  const { genesis: y, db: g, writer: b } = p
  if (!y) throw i.GENESIS_NOT_FIRST()
  const k = { id: 0, count: 0, parent: null, stats: I() }
  if (
    (await g.insert("@keet/threads", k),
    s.settings.roomType === d.Broadcast && (s.settings.isCallingDisabled = !0),
    await g.insert("@keet/system-digest", s),
    c && (await g.insert("@keet/room-capabilities", c)),
    m && (await g.insert("@keet-private-id/identity", m)),
    o && (await g.insert("@keet/room-config", o)),
    l)
  )
    for (const i of l) {
      const s = e.equals(i.attestation.memberKey, u.attestation.memberKey)
        ? { isAdmin: !0, isModerator: !0 }
        : { isAdmin: !1, isModerator: !0 }
      await n(t, i.profile, i.attestation, s, p)
    }
  await r(t, b.key, u.profile, u.attestation, { isActive: !0, isIndexing: !0 }, p)
  const w = await a(g, b.key)
  if (!u || !w) throw i.ABORT()
}
async function p({ version: e }, { db: t, writer: r, abi: n, hostcalls: o }) {
  const [d, c] = await Promise.all([a(t, r.key), t.get("@keet/system-digest")])
  if (!(9 !== e || (s(d) && d.status.isModerator))) return
  if (!s(d) || !d.status.isModerator) throw i.ABORT()
  if (c.abi.version >= e) return
  e > (c.settings.isExperimental ? n.max : n.production) &&
    o.interrupt({ unsupportedABI: e, digest: c })
  const m = c.abi.version
  ;((c.abi.version = e), await A(t, m, e), await t.insert("@keet/system-digest", c))
}
async function y({ key: e, settings: t }, { db: r, writer: n }) {
  const [o, d] = await Promise.all([a(r, n.key), r.get("@keet/system-digest")])
  if (!s(o)) throw i.INACTIVE_MEMBER()
  if (!o.status.isModerator) throw i.MODERATORS_ONLY()
  if (0 === e || e > m.length) throw i.INVALID_SYSTEM_SETTING()
  const c = d?.settings,
    u = m[e - 1],
    l = { ...c, [u]: t[u] }
  await r.insert("@keet/system-digest", { ...d, settings: l })
}
async function g({ peer: e }, { db: t, writer: i }) {
  const r = await a(t, i.key)
  s(r) && r.status.isModerator && (await t.insert("@keet/blind-peers", e))
}
async function b({ key: e }, { db: t, writer: i }) {
  const r = await a(t, i.key)
  s(r) && r.status.isModerator && (await t.delete("@keet/blind-peers", { key: e }))
}
async function k({ from: e, to: t, buildType: i }, { db: r, writer: n }) {
  const o = await a(r, n.key)
  s(o) &&
    o.status.isModerator &&
    (e < 14 && t >= 14 && (await v(r), await h(r)),
    e < 20 && t >= 20 && (await D(r)),
    e < 24 && t >= 24 && (await f(r)),
    e < 25 && t >= 25 && (await w(r, i)))
}
async function w(e, t) {
  const i = await e.get("@keet/system-digest")
  c[i.settings.buildType] ||
    (c[t] && ((i.settings.buildType = c[t]), await e.insert("@keet/system-digest", i)))
}
async function f(e) {
  if ((await e.get("@keet/system-digest")).settings.roomType === d.DirectMessage)
    for await (const t of e.find("@keet/members"))
      t.status.isModerator || ((t.status.isModerator = !0), await e.insert("@keet/members", t))
}
async function h(e) {
  if (!(await e.get("@keet-private-id/identity"))) return
  const t = { isPending: !1, isAccepted: !1, isRejected: !1, isDiscarded: !1, isSeen: !1 },
    i = []
  for (const s of await e.find("@keet-private-id/contact-requests").toArray()) {
    const { isSeen: a, isAccepted: r, isRejected: n, isDiscarded: o } = s.status
    ;(s.status.isAccepted && (s.status = { ...t, isAccepted: r, isSeen: a }),
      s.status.isRejected && (s.status = { ...t, isRejected: n, isSeen: a }),
      s.status.isDiscarded && (s.status = { ...t, isDiscarded: o, isSeen: a }),
      i.push(e.insert("@keet-private-id/contact-requests-v2", s)))
  }
  await Promise.all(i)
}
async function v(e) {
  if (!(await e.get("@keet-private-id/identity"))) return
  const t = []
  for (const { memberKey: i, roomKey: s } of await e.find("@keet-private-id/contacts").toArray()) {
    if (!s || !i) continue
    const a = await e.get("@keet-private-id/rooms", { roomKey: s })
    a && ((a.contact = i), t.push(e.insert("@keet-private-id/rooms", a)))
  }
  await Promise.all(t)
}
async function D(e) {
  const [t, i, s] = await Promise.all([
    e.get("@keet-private-id/identity"),
    e.get("@keet/threads", { id: 0 }),
    e.find("@keet/pinned-chat-messages").toArray(),
  ])
  !t && i && ((i.stats.chat.pinned = s.length), await e.insert("@keet/threads", i))
}
function A(e, t, i) {
  return Promise.resolve()
}
function M(e) {
  ;(e.add("@keet/genesis", l),
    e.add("@keet/upgrade", p),
    e.add("@keet/add-blind-peer", g),
    e.add("@keet/remove-blind-peer", b),
    e.add("@keet/update-system-settings", y),
    e.add("@keet/migrate-abi", k))
}
function I() {
  return {
    devices: { total: 0, active: 0 },
    members: { total: 0, active: 0, pending: 0 },
    chat: { clock: 0, pinned: 0, threads: 0, timestamp: 0 },
    files: { clock: 0 },
  }
}
module.exports = { [t]: M, Settings: u }