|
|
@@ -212,6 +212,12 @@ const {
|
|
|
|
buildMeshReplicationDiagnosticsJsonBody,
|
|
|
|
buildMeshReplicationDiagnosticsJsonBody,
|
|
|
|
signMeshReplicationDiagnosticsJson,
|
|
|
|
signMeshReplicationDiagnosticsJson,
|
|
|
|
verifyMeshReplicationDiagnosticsJson,
|
|
|
|
verifyMeshReplicationDiagnosticsJson,
|
|
|
|
|
|
|
|
buildMultiGuildSyncJsonBody,
|
|
|
|
|
|
|
|
signMultiGuildSyncJson,
|
|
|
|
|
|
|
|
verifyMultiGuildSyncJson,
|
|
|
|
|
|
|
|
buildPartitionHealDiagnosticsJsonBody,
|
|
|
|
|
|
|
|
signPartitionHealDiagnosticsJson,
|
|
|
|
|
|
|
|
verifyPartitionHealDiagnosticsJson,
|
|
|
|
formatAutomationScheduleDigestExport,
|
|
|
|
formatAutomationScheduleDigestExport,
|
|
|
|
mergeHookFailureDigests,
|
|
|
|
mergeHookFailureDigests,
|
|
|
|
buildAutomationScheduleDashboard,
|
|
|
|
buildAutomationScheduleDashboard,
|
|
|
@@ -1833,6 +1839,12 @@ class PearcordPlatform extends EventEmitter {
|
|
|
|
const meshReplicationDiagnosticsJsonHeal = await this._healMeshReplicationDiagnosticsCursorOnPartition(gid).catch(() => ({
|
|
|
|
const meshReplicationDiagnosticsJsonHeal = await this._healMeshReplicationDiagnosticsCursorOnPartition(gid).catch(() => ({
|
|
|
|
relisted: 0
|
|
|
|
relisted: 0
|
|
|
|
}))
|
|
|
|
}))
|
|
|
|
|
|
|
|
const multiGuildSyncJsonHeal = await this._healMultiGuildSyncExportCursorOnPartition(gid).catch(() => ({
|
|
|
|
|
|
|
|
relisted: 0
|
|
|
|
|
|
|
|
}))
|
|
|
|
|
|
|
|
const partitionHealDiagnosticsJsonHeal = await this._healPartitionHealDiagnosticsExportCursorOnPartition(gid).catch(() => ({
|
|
|
|
|
|
|
|
relisted: 0
|
|
|
|
|
|
|
|
}))
|
|
|
|
return {
|
|
|
|
return {
|
|
|
|
voiceApplied,
|
|
|
|
voiceApplied,
|
|
|
|
emojiSlots,
|
|
|
|
emojiSlots,
|
|
|
@@ -1899,7 +1911,9 @@ class PearcordPlatform extends EventEmitter {
|
|
|
|
deviceSyncJsonHeal,
|
|
|
|
deviceSyncJsonHeal,
|
|
|
|
discoveryListingExportJsonHeal,
|
|
|
|
discoveryListingExportJsonHeal,
|
|
|
|
federationSyncJsonHeal,
|
|
|
|
federationSyncJsonHeal,
|
|
|
|
meshReplicationDiagnosticsJsonHeal
|
|
|
|
meshReplicationDiagnosticsJsonHeal,
|
|
|
|
|
|
|
|
multiGuildSyncJsonHeal,
|
|
|
|
|
|
|
|
partitionHealDiagnosticsJsonHeal
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
@@ -11250,6 +11264,12 @@ class PearcordPlatform extends EventEmitter {
|
|
|
|
guildInstance.on('mesh-replication-diagnostics-json-sync', (payload) => {
|
|
|
|
guildInstance.on('mesh-replication-diagnostics-json-sync', (payload) => {
|
|
|
|
this._onMeshReplicationDiagnosticsJsonGossip(payload).catch(() => {})
|
|
|
|
this._onMeshReplicationDiagnosticsJsonGossip(payload).catch(() => {})
|
|
|
|
})
|
|
|
|
})
|
|
|
|
|
|
|
|
guildInstance.on('multi-guild-sync-json-sync', (payload) => {
|
|
|
|
|
|
|
|
this._onMultiGuildSyncJsonGossip(payload).catch(() => {})
|
|
|
|
|
|
|
|
})
|
|
|
|
|
|
|
|
guildInstance.on('partition-heal-diagnostics-json-sync', (payload) => {
|
|
|
|
|
|
|
|
this._onPartitionHealDiagnosticsJsonGossip(payload).catch(() => {})
|
|
|
|
|
|
|
|
})
|
|
|
|
guildInstance.on('message-search-request', (payload) => {
|
|
|
|
guildInstance.on('message-search-request', (payload) => {
|
|
|
|
this._onMessageSearchRequestGossip(payload).catch(() => {})
|
|
|
|
this._onMessageSearchRequestGossip(payload).catch(() => {})
|
|
|
|
})
|
|
|
|
})
|
|
|
@@ -27294,6 +27314,228 @@ class PearcordPlatform extends EventEmitter {
|
|
|
|
return row
|
|
|
|
return row
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
async _multiGuildSyncJsonRegistryEntries () {
|
|
|
|
|
|
|
|
const multi = this.exportMultiGuildSyncDiagnostics()
|
|
|
|
|
|
|
|
const entries = (multi.guildIds || []).slice(0, 32).map((gid) => {
|
|
|
|
|
|
|
|
const g = multi.guilds?.[gid] || {}
|
|
|
|
|
|
|
|
return {
|
|
|
|
|
|
|
|
guildId: gid,
|
|
|
|
|
|
|
|
meshBounded: !!g.meshBounded,
|
|
|
|
|
|
|
|
partitionHealInProgress: !!g.partitionHealInProgress,
|
|
|
|
|
|
|
|
syncState: g.syncHealth?.state || 'unknown',
|
|
|
|
|
|
|
|
exportedAt: multi.exportedAt || Date.now()
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
})
|
|
|
|
|
|
|
|
if (!entries.length && this.guild?.guild) {
|
|
|
|
|
|
|
|
entries.push({
|
|
|
|
|
|
|
|
guildId: this.guild.guild.id,
|
|
|
|
|
|
|
|
meshBounded: !!multi.activeGuildMeshBounded,
|
|
|
|
|
|
|
|
partitionHealInProgress: false,
|
|
|
|
|
|
|
|
syncState: 'local',
|
|
|
|
|
|
|
|
exportedAt: multi.exportedAt || Date.now()
|
|
|
|
|
|
|
|
})
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
return entries
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
async _partitionHealJsonRegistryEntries () {
|
|
|
|
|
|
|
|
const gid = this.guild?.guild?.id
|
|
|
|
|
|
|
|
if (!gid) return []
|
|
|
|
|
|
|
|
const entries = []
|
|
|
|
|
|
|
|
const active = this.exportPartitionHealDiagnostics(gid)
|
|
|
|
|
|
|
|
entries.push({
|
|
|
|
|
|
|
|
guildId: gid,
|
|
|
|
|
|
|
|
inProgress: !!active.inProgress,
|
|
|
|
|
|
|
|
cooldownRemainingMs: active.cooldownRemainingMs || 0,
|
|
|
|
|
|
|
|
meshBounded: !!active.meshBounded,
|
|
|
|
|
|
|
|
exportedAt: active.exportedAt || Date.now()
|
|
|
|
|
|
|
|
})
|
|
|
|
|
|
|
|
const multi = this.exportMultiGuildSyncDiagnostics()
|
|
|
|
|
|
|
|
for (const id of (multi.guildIds || []).slice(0, 16)) {
|
|
|
|
|
|
|
|
if (id === gid) continue
|
|
|
|
|
|
|
|
const ph = multi.guilds?.[id]?.partitionHeal
|
|
|
|
|
|
|
|
if (!ph) continue
|
|
|
|
|
|
|
|
entries.push({
|
|
|
|
|
|
|
|
guildId: id,
|
|
|
|
|
|
|
|
inProgress: !!ph.inProgress,
|
|
|
|
|
|
|
|
cooldownRemainingMs: ph.cooldownRemainingMs || 0,
|
|
|
|
|
|
|
|
meshBounded: !!ph.meshBounded,
|
|
|
|
|
|
|
|
exportedAt: Date.now()
|
|
|
|
|
|
|
|
})
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
return entries.slice(0, 32)
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
async getMultiGuildSyncJsonExport () {
|
|
|
|
|
|
|
|
const gid = this.guild?.guild?.id || null
|
|
|
|
|
|
|
|
const span = this.log.time('multi-guild.json', { spanKind: 'multi-guild.json', guildId: gid, context: 'read' })
|
|
|
|
|
|
|
|
try {
|
|
|
|
|
|
|
|
if (!this.guild?.guild) { span.end({ guildMultiGuildJsonCount: 0, skipped: true }); return null }
|
|
|
|
|
|
|
|
await this._initDeliveryReceipts(this.guild.guild.id)
|
|
|
|
|
|
|
|
const row = await this.deliveryReceipts.getMultiGuildSyncJsonExport()
|
|
|
|
|
|
|
|
if (!row?.signature) {
|
|
|
|
|
|
|
|
span.end({ guildMultiGuildJsonCount: row ? 1 : 0, hasSignature: false, bridgeKind: 'multi-guild.json' })
|
|
|
|
|
|
|
|
return row
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
const verified = verifyMultiGuildSyncJson(exportBodyFromSlice(row) || row.jsonBody, row.signature, { guildId: this.guild.guild.id, relaySecret: this.guild.guild.id })
|
|
|
|
|
|
|
|
const out = { ...row, signatureValid: verified.ok, guildCount: row.guildCount || 0 }
|
|
|
|
|
|
|
|
span.end({ guildMultiGuildJsonCount: 1, hasSignature: true, signatureValid: verified.ok, bridgeKind: 'multi-guild.json' })
|
|
|
|
|
|
|
|
return out
|
|
|
|
|
|
|
|
} catch (err) {
|
|
|
|
|
|
|
|
this.log.error('multi-guild.json error', { guildId: gid, context: 'read', error: err?.message || String(err) })
|
|
|
|
|
|
|
|
span.fail(err); throw err
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
async exportMultiGuildSyncJson (opts = {}) {
|
|
|
|
|
|
|
|
if (!this.guild?.guild) throw new Error('no guild')
|
|
|
|
|
|
|
|
const roles = await this._memberRoles()
|
|
|
|
|
|
|
|
if (!roleHasPermission(roles, PERMISSION.MANAGE_GUILD)) throw new Error('no permission to export multi-guild sync JSON')
|
|
|
|
|
|
|
|
const entries = await this._multiGuildSyncJsonRegistryEntries()
|
|
|
|
|
|
|
|
const jsonBody = buildMultiGuildSyncJsonBody(entries)
|
|
|
|
|
|
|
|
const signed = signMultiGuildSyncJson(jsonBody, { guildId: this.guild.guild.id, relaySecret: this.guild.guild.id })
|
|
|
|
|
|
|
|
const exportedAt = Date.now()
|
|
|
|
|
|
|
|
const meta = { guildId: this.guild.guild.id, exportedAt, guildCount: entries.length, signed: !!signed.signature, meshPushed: false }
|
|
|
|
|
|
|
|
this._lastMultiGuildSyncExport = meta
|
|
|
|
|
|
|
|
if (opts.recordMesh !== false) {
|
|
|
|
|
|
|
|
await this._initDeliveryReceipts(this.guild.guild.id)
|
|
|
|
|
|
|
|
await this.deliveryReceipts.recordMultiGuildSyncJsonExport({ jsonBody: signed.jsonBody || signed.json, signature: signed.signature, signatureAlg: signed.signatureAlg, exportedAt, guildCount: entries.length })
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
return { format: 'json', body: signed.json, signature: signed.signature, signatureAlg: signed.signatureAlg, exportedAt, guildCount: entries.length, meta }
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
async pushMultiGuildSyncJsonToMesh () {
|
|
|
|
|
|
|
|
const gid = this.guild?.guild?.id || null
|
|
|
|
|
|
|
|
const span = this.log.time('multi-guild.json', { spanKind: 'multi-guild.json', guildId: gid, context: 'mesh.push' })
|
|
|
|
|
|
|
|
try {
|
|
|
|
|
|
|
|
const exported = await this.exportMultiGuildSyncJson({ recordMesh: false })
|
|
|
|
|
|
|
|
if (!exported.signature) throw new Error('multi-guild sync json export not signed')
|
|
|
|
|
|
|
|
const payload = { guildId: this.guild.guild.id, exportedAt: exported.exportedAt || Date.now(), exportedBy: this.identity.user?.id || null, jsonBody: exported.body, signature: exported.signature, signatureAlg: exported.signatureAlg, guildCount: exported.guildCount || 0 }
|
|
|
|
|
|
|
|
if (this.guild.gossipMultiGuildSyncJsonSync) this.guild.gossipMultiGuildSyncJsonSync(payload)
|
|
|
|
|
|
|
|
this.emit('multi-guild-sync-json-sync', payload)
|
|
|
|
|
|
|
|
await this._initDeliveryReceipts(this.guild.guild.id)
|
|
|
|
|
|
|
|
await this.deliveryReceipts.recordMultiGuildSyncJsonExport({ jsonBody: exported.body, signature: exported.signature, signatureAlg: exported.signatureAlg, exportedAt: exported.exportedAt, guildCount: exported.guildCount })
|
|
|
|
|
|
|
|
this._lastMultiGuildSyncExport = { ...exported.meta, meshPushed: true }
|
|
|
|
|
|
|
|
span.end({ guildMultiGuildJsonCount: exported.guildCount || 0, meshPushed: true, bridgeKind: 'multi-guild.json' })
|
|
|
|
|
|
|
|
return exported
|
|
|
|
|
|
|
|
} catch (err) {
|
|
|
|
|
|
|
|
this.log.error('multi-guild.json error', { guildId: gid, context: 'mesh.push', error: err?.message || String(err) })
|
|
|
|
|
|
|
|
span.fail(err); throw err
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
async clearMultiGuildSyncJsonExports () {
|
|
|
|
|
|
|
|
if (!this.guild?.guild) throw new Error('no guild')
|
|
|
|
|
|
|
|
if (!(await this._hasPerm(PERMISSION.MANAGE_GUILD))) throw new Error('no permission to clear multi-guild sync JSON exports')
|
|
|
|
|
|
|
|
await this._initDeliveryReceipts(this.guild.guild.id)
|
|
|
|
|
|
|
|
const removed = await this.deliveryReceipts.clearMultiGuildSyncJsonExports()
|
|
|
|
|
|
|
|
this.emit('multi-guild-sync-json-cleared', { removed })
|
|
|
|
|
|
|
|
return { removed }
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
async getLastMultiGuildSyncExport () {
|
|
|
|
|
|
|
|
if (!this.guild?.guild) return null
|
|
|
|
|
|
|
|
const snap = this._lastMultiGuildSyncExport
|
|
|
|
|
|
|
|
if (snap?.guildId === this.guild.guild.id) return snap
|
|
|
|
|
|
|
|
return { guildId: this.guild.guild.id, exportedAt: Date.now(), guildCount: 0, signed: false, meshPushed: false }
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
async getPartitionHealDiagnosticsJsonExport () {
|
|
|
|
|
|
|
|
const gid = this.guild?.guild?.id || null
|
|
|
|
|
|
|
|
const span = this.log.time('partition-heal.json', { spanKind: 'partition-heal.json', guildId: gid, context: 'read' })
|
|
|
|
|
|
|
|
try {
|
|
|
|
|
|
|
|
if (!this.guild?.guild) { span.end({ guildPartitionHealJsonCount: 0, skipped: true }); return null }
|
|
|
|
|
|
|
|
await this._initDeliveryReceipts(this.guild.guild.id)
|
|
|
|
|
|
|
|
const row = await this.deliveryReceipts.getPartitionHealDiagnosticsJsonExport()
|
|
|
|
|
|
|
|
if (!row?.signature) {
|
|
|
|
|
|
|
|
span.end({ guildPartitionHealJsonCount: row ? 1 : 0, hasSignature: false, bridgeKind: 'partition-heal.json' })
|
|
|
|
|
|
|
|
return row
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
const verified = verifyPartitionHealDiagnosticsJson(exportBodyFromSlice(row) || row.jsonBody, row.signature, { guildId: this.guild.guild.id, relaySecret: this.guild.guild.id })
|
|
|
|
|
|
|
|
const out = { ...row, signatureValid: verified.ok, healCount: row.healCount || 0 }
|
|
|
|
|
|
|
|
span.end({ guildPartitionHealJsonCount: 1, hasSignature: true, signatureValid: verified.ok, bridgeKind: 'partition-heal.json' })
|
|
|
|
|
|
|
|
return out
|
|
|
|
|
|
|
|
} catch (err) {
|
|
|
|
|
|
|
|
this.log.error('partition-heal.json error', { guildId: gid, context: 'read', error: err?.message || String(err) })
|
|
|
|
|
|
|
|
span.fail(err); throw err
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
async exportPartitionHealDiagnosticsJson (opts = {}) {
|
|
|
|
|
|
|
|
if (!this.guild?.guild) throw new Error('no guild')
|
|
|
|
|
|
|
|
const roles = await this._memberRoles()
|
|
|
|
|
|
|
|
if (!roleHasPermission(roles, PERMISSION.MANAGE_GUILD)) throw new Error('no permission to export partition heal diagnostics JSON')
|
|
|
|
|
|
|
|
const entries = await this._partitionHealJsonRegistryEntries()
|
|
|
|
|
|
|
|
const jsonBody = buildPartitionHealDiagnosticsJsonBody(entries)
|
|
|
|
|
|
|
|
const signed = signPartitionHealDiagnosticsJson(jsonBody, { guildId: this.guild.guild.id, relaySecret: this.guild.guild.id })
|
|
|
|
|
|
|
|
const exportedAt = Date.now()
|
|
|
|
|
|
|
|
const meta = { guildId: this.guild.guild.id, exportedAt, healCount: entries.length, signed: !!signed.signature, meshPushed: false }
|
|
|
|
|
|
|
|
this._lastPartitionHealExport = meta
|
|
|
|
|
|
|
|
if (opts.recordMesh !== false) {
|
|
|
|
|
|
|
|
await this._initDeliveryReceipts(this.guild.guild.id)
|
|
|
|
|
|
|
|
await this.deliveryReceipts.recordPartitionHealDiagnosticsJsonExport({ jsonBody: signed.jsonBody || signed.json, signature: signed.signature, signatureAlg: signed.signatureAlg, exportedAt, healCount: entries.length })
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
return { format: 'json', body: signed.json, signature: signed.signature, signatureAlg: signed.signatureAlg, exportedAt, healCount: entries.length, meta }
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
async pushPartitionHealDiagnosticsJsonToMesh () {
|
|
|
|
|
|
|
|
const gid = this.guild?.guild?.id || null
|
|
|
|
|
|
|
|
const span = this.log.time('partition-heal.json', { spanKind: 'partition-heal.json', guildId: gid, context: 'mesh.push' })
|
|
|
|
|
|
|
|
try {
|
|
|
|
|
|
|
|
const exported = await this.exportPartitionHealDiagnosticsJson({ recordMesh: false })
|
|
|
|
|
|
|
|
if (!exported.signature) throw new Error('partition heal diagnostics json not signed')
|
|
|
|
|
|
|
|
const payload = { guildId: this.guild.guild.id, exportedAt: exported.exportedAt || Date.now(), exportedBy: this.identity.user?.id || null, jsonBody: exported.body, signature: exported.signature, signatureAlg: exported.signatureAlg, healCount: exported.healCount || 0 }
|
|
|
|
|
|
|
|
if (this.guild.gossipPartitionHealDiagnosticsJsonSync) this.guild.gossipPartitionHealDiagnosticsJsonSync(payload)
|
|
|
|
|
|
|
|
this.emit('partition-heal-diagnostics-json-sync', payload)
|
|
|
|
|
|
|
|
await this._initDeliveryReceipts(this.guild.guild.id)
|
|
|
|
|
|
|
|
await this.deliveryReceipts.recordPartitionHealDiagnosticsJsonExport({ jsonBody: exported.body, signature: exported.signature, signatureAlg: exported.signatureAlg, exportedAt: exported.exportedAt, healCount: exported.healCount })
|
|
|
|
|
|
|
|
this._lastPartitionHealExport = { ...exported.meta, meshPushed: true }
|
|
|
|
|
|
|
|
span.end({ guildPartitionHealJsonCount: exported.healCount || 0, meshPushed: true, bridgeKind: 'partition-heal.json' })
|
|
|
|
|
|
|
|
return exported
|
|
|
|
|
|
|
|
} catch (err) {
|
|
|
|
|
|
|
|
this.log.error('partition-heal.json error', { guildId: gid, context: 'mesh.push', error: err?.message || String(err) })
|
|
|
|
|
|
|
|
span.fail(err); throw err
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
async clearPartitionHealDiagnosticsJsonExports () {
|
|
|
|
|
|
|
|
if (!this.guild?.guild) throw new Error('no guild')
|
|
|
|
|
|
|
|
if (!(await this._hasPerm(PERMISSION.MANAGE_GUILD))) throw new Error('no permission to clear partition heal diagnostics JSON exports')
|
|
|
|
|
|
|
|
await this._initDeliveryReceipts(this.guild.guild.id)
|
|
|
|
|
|
|
|
const removed = await this.deliveryReceipts.clearPartitionHealDiagnosticsJsonExports()
|
|
|
|
|
|
|
|
this.emit('partition-heal-diagnostics-json-cleared', { removed })
|
|
|
|
|
|
|
|
return { removed }
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
async getLastPartitionHealExport () {
|
|
|
|
|
|
|
|
if (!this.guild?.guild) return null
|
|
|
|
|
|
|
|
const snap = this._lastPartitionHealExport
|
|
|
|
|
|
|
|
if (snap?.guildId === this.guild.guild.id) return snap
|
|
|
|
|
|
|
|
return { guildId: this.guild.guild.id, exportedAt: Date.now(), healCount: 0, signed: false, meshPushed: false }
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
async _onMultiGuildSyncJsonGossip (payload) {
|
|
|
|
|
|
|
|
if (!payload?.guildId || !payload?.jsonBody || !payload?.signature) return null
|
|
|
|
|
|
|
|
if (this.guild?.guild?.id !== payload.guildId) return null
|
|
|
|
|
|
|
|
await this._initDeliveryReceipts(payload.guildId)
|
|
|
|
|
|
|
|
this._shouldGossipMultiGuildSyncRegistryJson(payload)
|
|
|
|
|
|
|
|
const row = await this.deliveryReceipts.ingestMultiGuildSyncJsonSlice(payload.guildId, payload)
|
|
|
|
|
|
|
|
if (row?.duplicate) this._multiGuildSyncJsonDuplicateAt = row.exportedAt || payload.exportedAt || null
|
|
|
|
|
|
|
|
if (row) this.emit('multi-guild-sync-json-sync', payload)
|
|
|
|
|
|
|
|
return row
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
async _onPartitionHealDiagnosticsJsonGossip (payload) {
|
|
|
|
|
|
|
|
if (!payload?.guildId || !payload?.jsonBody || !payload?.signature) return null
|
|
|
|
|
|
|
|
if (this.guild?.guild?.id !== payload.guildId) return null
|
|
|
|
|
|
|
|
await this._initDeliveryReceipts(payload.guildId)
|
|
|
|
|
|
|
|
this._shouldGossipPartitionHealDiagnosticsRegistryJson(payload)
|
|
|
|
|
|
|
|
const row = await this.deliveryReceipts.ingestPartitionHealDiagnosticsJsonSlice(payload.guildId, payload)
|
|
|
|
|
|
|
|
if (row?.duplicate) this._partitionHealDiagnosticsJsonDuplicateAt = row.exportedAt || payload.exportedAt || null
|
|
|
|
|
|
|
|
if (row) this.emit('partition-heal-diagnostics-json-sync', payload)
|
|
|
|
|
|
|
|
return row
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
async getAuditExportSchedule () {
|
|
|
|
async getAuditExportSchedule () {
|
|
|
|
if (!this.guild?.guild) {
|
|
|
|
if (!this.guild?.guild) {
|
|
|
@@ -32245,6 +32487,14 @@ class PearcordPlatform extends EventEmitter {
|
|
|
|
let meshReplicationDiagnosticsJsonMeta = null
|
|
|
|
let meshReplicationDiagnosticsJsonMeta = null
|
|
|
|
let meshReplicationDiagnosticsJsonRows = []
|
|
|
|
let meshReplicationDiagnosticsJsonRows = []
|
|
|
|
let lastMeshReplicationExport = null
|
|
|
|
let lastMeshReplicationExport = null
|
|
|
|
|
|
|
|
let multiGuildSyncJsonMeta = null
|
|
|
|
|
|
|
|
let multiGuildSyncJsonRows = []
|
|
|
|
|
|
|
|
let lastMultiGuildSyncExport = null
|
|
|
|
|
|
|
|
let partitionHealDiagnosticsJsonMeta = null
|
|
|
|
|
|
|
|
let partitionHealDiagnosticsJsonRows = []
|
|
|
|
|
|
|
|
let lastPartitionHealExport = null
|
|
|
|
|
|
|
|
let guildMultiGuildSyncEntries = []
|
|
|
|
|
|
|
|
let guildPartitionHealEntries = []
|
|
|
|
let guildFederationSyncEntries = []
|
|
|
|
let guildFederationSyncEntries = []
|
|
|
|
let guildMeshReplicationChannels = []
|
|
|
|
let guildMeshReplicationChannels = []
|
|
|
|
let guildPairedDevices = []
|
|
|
|
let guildPairedDevices = []
|
|
|
@@ -32545,6 +32795,34 @@ class PearcordPlatform extends EventEmitter {
|
|
|
|
return { ...row, signatureValid: verified.ok }
|
|
|
|
return { ...row, signatureValid: verified.ok }
|
|
|
|
})
|
|
|
|
})
|
|
|
|
lastMeshReplicationExport = await this.getLastMeshReplicationExport()
|
|
|
|
lastMeshReplicationExport = await this.getLastMeshReplicationExport()
|
|
|
|
|
|
|
|
multiGuildSyncJsonMeta = await this.getMultiGuildSyncJsonExport().catch(() => null)
|
|
|
|
|
|
|
|
multiGuildSyncJsonRows = (await this.deliveryReceipts.listMultiGuildSyncJsonExports(32)).map((row) => {
|
|
|
|
|
|
|
|
if (!row?.signature || !guild?.id) return row
|
|
|
|
|
|
|
|
const verified = verifyMultiGuildSyncJson(exportBodyFromSlice(row) || row.jsonBody, row.signature, { guildId: guild.id, relaySecret: guild.id })
|
|
|
|
|
|
|
|
return { ...row, signatureValid: verified.ok }
|
|
|
|
|
|
|
|
})
|
|
|
|
|
|
|
|
lastMultiGuildSyncExport = await this.getLastMultiGuildSyncExport()
|
|
|
|
|
|
|
|
partitionHealDiagnosticsJsonMeta = await this.getPartitionHealDiagnosticsJsonExport().catch(() => null)
|
|
|
|
|
|
|
|
partitionHealDiagnosticsJsonRows = (await this.deliveryReceipts.listPartitionHealDiagnosticsJsonExports(32)).map((row) => {
|
|
|
|
|
|
|
|
if (!row?.signature || !guild?.id) return row
|
|
|
|
|
|
|
|
const verified = verifyPartitionHealDiagnosticsJson(exportBodyFromSlice(row) || row.jsonBody, row.signature, { guildId: guild.id, relaySecret: guild.id })
|
|
|
|
|
|
|
|
return { ...row, signatureValid: verified.ok }
|
|
|
|
|
|
|
|
})
|
|
|
|
|
|
|
|
lastPartitionHealExport = await this.getLastPartitionHealExport()
|
|
|
|
|
|
|
|
const multiEntries = await this._multiGuildSyncJsonRegistryEntries().catch(() => [])
|
|
|
|
|
|
|
|
guildMultiGuildSyncEntries = multiEntries.slice(0, 16).map((r) => ({
|
|
|
|
|
|
|
|
id: r.guildId || guild.id,
|
|
|
|
|
|
|
|
name: `Guild ${String(r.guildId || '').slice(0, 8)}`,
|
|
|
|
|
|
|
|
role: r.meshBounded ? 'bounded' : (r.partitionHealInProgress ? 'healing' : 'synced'),
|
|
|
|
|
|
|
|
updatedAt: r.exportedAt || Date.now()
|
|
|
|
|
|
|
|
}))
|
|
|
|
|
|
|
|
const healEntries = await this._partitionHealJsonRegistryEntries().catch(() => [])
|
|
|
|
|
|
|
|
guildPartitionHealEntries = healEntries.slice(0, 16).map((r) => ({
|
|
|
|
|
|
|
|
id: r.guildId || guild.id,
|
|
|
|
|
|
|
|
name: r.inProgress ? 'Heal in progress' : 'Partition idle',
|
|
|
|
|
|
|
|
role: (r.cooldownRemainingMs || 0) > 0 ? 'cooldown' : 'ready',
|
|
|
|
|
|
|
|
updatedAt: r.exportedAt || Date.now()
|
|
|
|
|
|
|
|
}))
|
|
|
|
const fedEntries = await this._federationSyncJsonRegistryEntries().catch(() => [])
|
|
|
|
const fedEntries = await this._federationSyncJsonRegistryEntries().catch(() => [])
|
|
|
|
guildFederationSyncEntries = fedEntries.slice(0, 16).map((r) => ({
|
|
|
|
guildFederationSyncEntries = fedEntries.slice(0, 16).map((r) => ({
|
|
|
|
id: r.federationId || guild.id,
|
|
|
|
id: r.federationId || guild.id,
|
|
|
@@ -33246,6 +33524,14 @@ class PearcordPlatform extends EventEmitter {
|
|
|
|
meshReplicationDiagnosticsJsonMeta,
|
|
|
|
meshReplicationDiagnosticsJsonMeta,
|
|
|
|
meshReplicationDiagnosticsJsonRows,
|
|
|
|
meshReplicationDiagnosticsJsonRows,
|
|
|
|
lastMeshReplicationExport,
|
|
|
|
lastMeshReplicationExport,
|
|
|
|
|
|
|
|
multiGuildSyncJsonMeta,
|
|
|
|
|
|
|
|
multiGuildSyncJsonRows,
|
|
|
|
|
|
|
|
lastMultiGuildSyncExport,
|
|
|
|
|
|
|
|
partitionHealDiagnosticsJsonMeta,
|
|
|
|
|
|
|
|
partitionHealDiagnosticsJsonRows,
|
|
|
|
|
|
|
|
lastPartitionHealExport,
|
|
|
|
|
|
|
|
guildMultiGuildSyncEntries,
|
|
|
|
|
|
|
|
guildPartitionHealEntries,
|
|
|
|
guildFederationSyncEntries,
|
|
|
|
guildFederationSyncEntries,
|
|
|
|
guildMeshReplicationChannels,
|
|
|
|
guildMeshReplicationChannels,
|
|
|
|
guildPairedDevices,
|
|
|
|
guildPairedDevices,
|
|
|
@@ -33258,6 +33544,10 @@ class PearcordPlatform extends EventEmitter {
|
|
|
|
(federationSyncJsonRows || []).length + (guildFederationSyncEntries || []).length,
|
|
|
|
(federationSyncJsonRows || []).length + (guildFederationSyncEntries || []).length,
|
|
|
|
guildMeshJsonCount:
|
|
|
|
guildMeshJsonCount:
|
|
|
|
(meshReplicationDiagnosticsJsonRows || []).length + (guildMeshReplicationChannels || []).length,
|
|
|
|
(meshReplicationDiagnosticsJsonRows || []).length + (guildMeshReplicationChannels || []).length,
|
|
|
|
|
|
|
|
guildMultiGuildJsonCount:
|
|
|
|
|
|
|
|
(multiGuildSyncJsonRows || []).length + (guildMultiGuildSyncEntries || []).length,
|
|
|
|
|
|
|
|
guildPartitionHealJsonCount:
|
|
|
|
|
|
|
|
(partitionHealDiagnosticsJsonRows || []).length + (guildPartitionHealEntries || []).length,
|
|
|
|
automationScheduleDashboard,
|
|
|
|
automationScheduleDashboard,
|
|
|
|
automationHealthDashboard,
|
|
|
|
automationHealthDashboard,
|
|
|
|
automationDigestNotifyPrefs,
|
|
|
|
automationDigestNotifyPrefs,
|
|
|
@@ -33885,6 +34175,8 @@ const { deviceJsonMixin } = require('./device-json-mixin')
|
|
|
|
const { discoveryJsonMixin } = require('./discovery-json-mixin')
|
|
|
|
const { discoveryJsonMixin } = require('./discovery-json-mixin')
|
|
|
|
const { federationJsonMixin } = require('./federation-json-mixin')
|
|
|
|
const { federationJsonMixin } = require('./federation-json-mixin')
|
|
|
|
const { meshJsonMixin } = require('./mesh-json-mixin')
|
|
|
|
const { meshJsonMixin } = require('./mesh-json-mixin')
|
|
|
|
|
|
|
|
const { multiGuildJsonMixin } = require('./multi-guild-json-mixin')
|
|
|
|
|
|
|
|
const { partitionHealJsonMixin } = require('./partition-heal-json-mixin')
|
|
|
|
Object.assign(PearcordPlatform.prototype, pollSchedulingMixin)
|
|
|
|
Object.assign(PearcordPlatform.prototype, pollSchedulingMixin)
|
|
|
|
Object.assign(PearcordPlatform.prototype, notificationsActivityMixin)
|
|
|
|
Object.assign(PearcordPlatform.prototype, notificationsActivityMixin)
|
|
|
|
Object.assign(PearcordPlatform.prototype, userSettingsMixin)
|
|
|
|
Object.assign(PearcordPlatform.prototype, userSettingsMixin)
|
|
|
@@ -33928,3 +34220,5 @@ Object.assign(PearcordPlatform.prototype, deviceJsonMixin)
|
|
|
|
Object.assign(PearcordPlatform.prototype, discoveryJsonMixin)
|
|
|
|
Object.assign(PearcordPlatform.prototype, discoveryJsonMixin)
|
|
|
|
Object.assign(PearcordPlatform.prototype, federationJsonMixin)
|
|
|
|
Object.assign(PearcordPlatform.prototype, federationJsonMixin)
|
|
|
|
Object.assign(PearcordPlatform.prototype, meshJsonMixin)
|
|
|
|
Object.assign(PearcordPlatform.prototype, meshJsonMixin)
|
|
|
|
|
|
|
|
Object.assign(PearcordPlatform.prototype, multiGuildJsonMixin)
|
|
|
|
|
|
|
|
Object.assign(PearcordPlatform.prototype, partitionHealJsonMixin)
|
|
|
|