|
|
|
@@ -1845,6 +1845,12 @@ class PearcordPlatform extends EventEmitter {
|
|
|
|
|
const partitionHealDiagnosticsJsonHeal = await this._healPartitionHealDiagnosticsExportCursorOnPartition(gid).catch(() => ({
|
|
|
|
|
relisted: 0
|
|
|
|
|
}))
|
|
|
|
|
const channelFollowJsonHeal = await this._healChannelFollowJsonExportCursorOnPartition(gid).catch(() => ({
|
|
|
|
|
relisted: 0
|
|
|
|
|
}))
|
|
|
|
|
const guildWidgetJsonHeal = await this._healGuildWidgetJsonExportCursorOnPartition(gid).catch(() => ({
|
|
|
|
|
relisted: 0
|
|
|
|
|
}))
|
|
|
|
|
return {
|
|
|
|
|
voiceApplied,
|
|
|
|
|
emojiSlots,
|
|
|
|
@@ -1913,7 +1919,9 @@ class PearcordPlatform extends EventEmitter {
|
|
|
|
|
federationSyncJsonHeal,
|
|
|
|
|
meshReplicationDiagnosticsJsonHeal,
|
|
|
|
|
multiGuildSyncJsonHeal,
|
|
|
|
|
partitionHealDiagnosticsJsonHeal
|
|
|
|
|
partitionHealDiagnosticsJsonHeal,
|
|
|
|
|
channelFollowJsonHeal,
|
|
|
|
|
guildWidgetJsonHeal
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
@@ -26321,10 +26329,40 @@ class PearcordPlatform extends EventEmitter {
|
|
|
|
|
return { format: 'json', body: signed.json, signature: signed.signature, signatureAlg: signed.signatureAlg, exportedAt, followCount: entries.length, meta }
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
async getChannelFollowExportJsonExport () {
|
|
|
|
|
const gid = this.guild?.guild?.id || null
|
|
|
|
|
const span = this.log.time('channel-follow.json', { spanKind: 'channel-follow.json', guildId: gid, context: 'read' })
|
|
|
|
|
try {
|
|
|
|
|
if (!this.guild?.guild) { span.end({ guildChannelFollowJsonCount: 0, skipped: true }); return null }
|
|
|
|
|
await this._initDeliveryReceipts(this.guild.guild.id)
|
|
|
|
|
const row = await this.deliveryReceipts.getChannelFollowExportJsonExport()
|
|
|
|
|
if (!row?.signature) {
|
|
|
|
|
span.end({ guildChannelFollowJsonCount: row ? 1 : 0, hasSignature: false, bridgeKind: 'channel-follow.json' })
|
|
|
|
|
return row
|
|
|
|
|
}
|
|
|
|
|
const verified = verifyChannelFollowExportJson(exportBodyFromSlice(row) || row.jsonBody, row.signature, { guildId: this.guild.guild.id, relaySecret: this.guild.guild.id })
|
|
|
|
|
const out = { ...row, signatureValid: verified.ok, followCount: row.followCount || 0 }
|
|
|
|
|
span.end({ guildChannelFollowJsonCount: 1, hasSignature: true, signatureValid: verified.ok, bridgeKind: 'channel-follow.json' })
|
|
|
|
|
return out
|
|
|
|
|
} catch (err) {
|
|
|
|
|
this.log.error('channel-follow.json error', { guildId: gid, context: 'read', error: err?.message || String(err) })
|
|
|
|
|
span.fail(err); throw err
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
async clearChannelFollowExportJsonExports () {
|
|
|
|
|
if (!this.guild?.guild) throw new Error('no guild')
|
|
|
|
|
if (!(await this._hasPerm(PERMISSION.MANAGE_GUILD))) throw new Error('no permission to clear channel follow JSON exports')
|
|
|
|
|
await this._initDeliveryReceipts(this.guild.guild.id)
|
|
|
|
|
const removed = await this.deliveryReceipts.clearChannelFollowExportJsonExports()
|
|
|
|
|
this.emit('channel-follow-export-json-cleared', { removed })
|
|
|
|
|
return { removed }
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
async pushChannelFollowExportToMesh () {
|
|
|
|
|
const gid = this.guild?.guild?.id || null
|
|
|
|
|
const span = this.log.time('notification.json', {
|
|
|
|
|
spanKind: 'notification.json',
|
|
|
|
|
const span = this.log.time('channel-follow.json', {
|
|
|
|
|
spanKind: 'channel-follow.json',
|
|
|
|
|
guildId: gid,
|
|
|
|
|
context: 'mesh.channel-follow'
|
|
|
|
|
})
|
|
|
|
@@ -26356,13 +26394,13 @@ class PearcordPlatform extends EventEmitter {
|
|
|
|
|
meshPushed: true
|
|
|
|
|
}
|
|
|
|
|
span.end({
|
|
|
|
|
guildNotificationJsonCount: exported.followCount || 0,
|
|
|
|
|
guildChannelFollowJsonCount: exported.followCount || 0,
|
|
|
|
|
meshPushed: true,
|
|
|
|
|
bridgeKind: 'notification.json'
|
|
|
|
|
bridgeKind: 'channel-follow.json'
|
|
|
|
|
})
|
|
|
|
|
return exported
|
|
|
|
|
} catch (err) {
|
|
|
|
|
this.log.error('notification.json error', {
|
|
|
|
|
this.log.error('channel-follow.json error', {
|
|
|
|
|
guildId: gid,
|
|
|
|
|
context: 'mesh.channel-follow',
|
|
|
|
|
error: err?.message || String(err)
|
|
|
|
@@ -26544,9 +26582,39 @@ class PearcordPlatform extends EventEmitter {
|
|
|
|
|
return { format: 'json', body: signed.json, signature: signed.signature, signatureAlg: signed.signatureAlg, exportedAt, widgetCount: entries.length, meta }
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
async getGuildWidgetExportJsonExport () {
|
|
|
|
|
const gid = this.guild?.guild?.id || null
|
|
|
|
|
const span = this.log.time('guild-widget.json', { spanKind: 'guild-widget.json', guildId: gid, context: 'read' })
|
|
|
|
|
try {
|
|
|
|
|
if (!this.guild?.guild) { span.end({ guildWidgetJsonCount: 0, skipped: true }); return null }
|
|
|
|
|
await this._initDeliveryReceipts(this.guild.guild.id)
|
|
|
|
|
const row = await this.deliveryReceipts.getGuildWidgetExportJsonExport()
|
|
|
|
|
if (!row?.signature) {
|
|
|
|
|
span.end({ guildWidgetJsonCount: row ? 1 : 0, hasSignature: false, bridgeKind: 'guild-widget.json' })
|
|
|
|
|
return row
|
|
|
|
|
}
|
|
|
|
|
const verified = verifyGuildWidgetExportJson(exportBodyFromSlice(row) || row.jsonBody, row.signature, { guildId: this.guild.guild.id, relaySecret: this.guild.guild.id })
|
|
|
|
|
const out = { ...row, signatureValid: verified.ok, widgetCount: row.widgetCount || 0 }
|
|
|
|
|
span.end({ guildWidgetJsonCount: 1, hasSignature: true, signatureValid: verified.ok, bridgeKind: 'guild-widget.json' })
|
|
|
|
|
return out
|
|
|
|
|
} catch (err) {
|
|
|
|
|
this.log.error('guild-widget.json error', { guildId: gid, context: 'read', error: err?.message || String(err) })
|
|
|
|
|
span.fail(err); throw err
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
async clearGuildWidgetExportJsonExports () {
|
|
|
|
|
if (!this.guild?.guild) throw new Error('no guild')
|
|
|
|
|
if (!(await this._hasPerm(PERMISSION.MANAGE_GUILD))) throw new Error('no permission to clear guild widget JSON exports')
|
|
|
|
|
await this._initDeliveryReceipts(this.guild.guild.id)
|
|
|
|
|
const removed = await this.deliveryReceipts.clearGuildWidgetExportJsonExports()
|
|
|
|
|
this.emit('guild-widget-export-json-cleared', { removed })
|
|
|
|
|
return { removed }
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
async pushGuildWidgetExportToMesh () {
|
|
|
|
|
const gid = this.guild?.guild?.id || null
|
|
|
|
|
const span = this.log.time('status.json', { spanKind: 'status.json', guildId: gid, context: 'mesh.guild-widget' })
|
|
|
|
|
const span = this.log.time('guild-widget.json', { spanKind: 'guild-widget.json', guildId: gid, context: 'mesh.guild-widget' })
|
|
|
|
|
try {
|
|
|
|
|
const exported = await this.exportGuildWidgetMesh({ recordMesh: false })
|
|
|
|
|
if (!exported.signature) throw new Error('guild widget export json not signed')
|
|
|
|
@@ -26555,10 +26623,10 @@ class PearcordPlatform extends EventEmitter {
|
|
|
|
|
this.emit('guild-widget-export-json-sync', payload)
|
|
|
|
|
await this.deliveryReceipts.recordGuildWidgetExportJson({ jsonBody: exported.body, jsonBody: exported.body, signature: exported.signature, signatureAlg: exported.signatureAlg, exportedAt: exported.exportedAt, widgetCount: exported.widgetCount })
|
|
|
|
|
this._lastGuildWidgetExport = { ...exported.meta, meshPushed: true }
|
|
|
|
|
span.end({ guildStatusJsonCount: exported.widgetCount || 0, meshPushed: true, bridgeKind: 'status.json' })
|
|
|
|
|
span.end({ guildWidgetJsonCount: exported.widgetCount || 0, meshPushed: true, bridgeKind: 'guild-widget.json' })
|
|
|
|
|
return exported
|
|
|
|
|
} catch (err) {
|
|
|
|
|
this.log.error('status.json error', { guildId: gid, context: 'mesh.guild-widget', error: err?.message || String(err) })
|
|
|
|
|
this.log.error('guild-widget.json error', { guildId: gid, context: 'mesh.guild-widget', error: err?.message || String(err) })
|
|
|
|
|
span.fail(err); throw err
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
@@ -27314,6 +27382,37 @@ class PearcordPlatform extends EventEmitter {
|
|
|
|
|
return row
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
async _channelFollowJsonRegistryEntries () {
|
|
|
|
|
if (!this.guild?.guild) return []
|
|
|
|
|
const follows = this.announcements
|
|
|
|
|
? await this.announcements.listGuildFollows(this.guild.guild.id).catch(() => [])
|
|
|
|
|
: []
|
|
|
|
|
if (!follows.length) {
|
|
|
|
|
return [{ channelId: '', userId: '', followState: 'none', exportedAt: Date.now() }]
|
|
|
|
|
}
|
|
|
|
|
return follows.slice(0, 32).map((row) => ({
|
|
|
|
|
channelId: row.channelId || '',
|
|
|
|
|
userId: row.userId || '',
|
|
|
|
|
followState: row.active === false ? 'inactive' : 'active',
|
|
|
|
|
exportedAt: Date.now()
|
|
|
|
|
}))
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
async _guildWidgetJsonRegistryEntries () {
|
|
|
|
|
if (!this.guild?.guild) return []
|
|
|
|
|
const g = this.guild.guild
|
|
|
|
|
const channels = await this.guild.listChannels().catch(() => [])
|
|
|
|
|
const members = await this.guild.listMembers().catch(() => [])
|
|
|
|
|
return [{
|
|
|
|
|
guildId: g.id,
|
|
|
|
|
widgetName: g.name || 'Widget',
|
|
|
|
|
widgetState: g.publicListing ? 'public' : 'private',
|
|
|
|
|
channelCount: channels.length,
|
|
|
|
|
memberCount: members.length,
|
|
|
|
|
exportedAt: Date.now()
|
|
|
|
|
}]
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
async _multiGuildSyncJsonRegistryEntries () {
|
|
|
|
|
const multi = this.exportMultiGuildSyncDiagnostics()
|
|
|
|
|
const entries = (multi.guildIds || []).slice(0, 32).map((gid) => {
|
|
|
|
@@ -32460,12 +32559,16 @@ class PearcordPlatform extends EventEmitter {
|
|
|
|
|
let notificationOverrideJsonMeta = null
|
|
|
|
|
let notificationOverrideJsonRows = []
|
|
|
|
|
let channelFollowExportJsonRows = []
|
|
|
|
|
let channelFollowExportJsonMeta = null
|
|
|
|
|
let lastChannelFollowExport = null
|
|
|
|
|
let guildChannelFollowEntries = []
|
|
|
|
|
let guildNotificationOverrides = []
|
|
|
|
|
let customStatusJsonMeta = null
|
|
|
|
|
let customStatusJsonRows = []
|
|
|
|
|
let guildWidgetExportJsonRows = []
|
|
|
|
|
let guildWidgetExportJsonMeta = null
|
|
|
|
|
let lastGuildWidgetExport = null
|
|
|
|
|
let guildWidgetConfigEntries = []
|
|
|
|
|
let guildCustomStatuses = []
|
|
|
|
|
let activityInviteJsonMeta = null
|
|
|
|
|
let activityInviteJsonRows = []
|
|
|
|
@@ -32809,6 +32912,34 @@ class PearcordPlatform extends EventEmitter {
|
|
|
|
|
return { ...row, signatureValid: verified.ok }
|
|
|
|
|
})
|
|
|
|
|
lastPartitionHealExport = await this.getLastPartitionHealExport()
|
|
|
|
|
channelFollowExportJsonMeta = await this.getChannelFollowExportJsonExport().catch(() => null)
|
|
|
|
|
channelFollowExportJsonRows = (await this.deliveryReceipts.listChannelFollowExportJsonExports(32)).map((row) => {
|
|
|
|
|
if (!row?.signature || !guild?.id) return row
|
|
|
|
|
const verified = verifyChannelFollowExportJson(exportBodyFromSlice(row) || row.jsonBody, row.signature, { guildId: guild.id, relaySecret: guild.id })
|
|
|
|
|
return { ...row, signatureValid: verified.ok }
|
|
|
|
|
})
|
|
|
|
|
lastChannelFollowExport = await this.getLastChannelFollowExport().catch(() => null)
|
|
|
|
|
guildWidgetExportJsonMeta = await this.getGuildWidgetExportJsonExport().catch(() => null)
|
|
|
|
|
guildWidgetExportJsonRows = (await this.deliveryReceipts.listGuildWidgetExportJsonExports(32)).map((row) => {
|
|
|
|
|
if (!row?.signature || !guild?.id) return row
|
|
|
|
|
const verified = verifyGuildWidgetExportJson(exportBodyFromSlice(row) || row.jsonBody, row.signature, { guildId: guild.id, relaySecret: guild.id })
|
|
|
|
|
return { ...row, signatureValid: verified.ok }
|
|
|
|
|
})
|
|
|
|
|
lastGuildWidgetExport = await this.getLastGuildWidgetExport().catch(() => null)
|
|
|
|
|
const followEntries = await this._channelFollowJsonRegistryEntries().catch(() => [])
|
|
|
|
|
guildChannelFollowEntries = followEntries.slice(0, 16).map((r) => ({
|
|
|
|
|
id: r.channelId || 'follow',
|
|
|
|
|
name: r.channelId ? `Channel ${String(r.channelId).slice(0, 8)}` : 'No follows',
|
|
|
|
|
role: r.followState || 'active',
|
|
|
|
|
updatedAt: r.exportedAt || Date.now()
|
|
|
|
|
}))
|
|
|
|
|
const widgetEntries = await this._guildWidgetJsonRegistryEntries().catch(() => [])
|
|
|
|
|
guildWidgetConfigEntries = widgetEntries.slice(0, 16).map((r) => ({
|
|
|
|
|
id: r.guildId || guild.id,
|
|
|
|
|
name: r.widgetName || 'Widget',
|
|
|
|
|
role: r.widgetState || 'private',
|
|
|
|
|
updatedAt: r.exportedAt || Date.now()
|
|
|
|
|
}))
|
|
|
|
|
const multiEntries = await this._multiGuildSyncJsonRegistryEntries().catch(() => [])
|
|
|
|
|
guildMultiGuildSyncEntries = multiEntries.slice(0, 16).map((r) => ({
|
|
|
|
|
id: r.guildId || guild.id,
|
|
|
|
@@ -33489,6 +33620,10 @@ class PearcordPlatform extends EventEmitter {
|
|
|
|
|
notificationOverrideJsonMeta,
|
|
|
|
|
notificationOverrideJsonRows,
|
|
|
|
|
channelFollowExportJsonRows,
|
|
|
|
|
channelFollowExportJsonMeta,
|
|
|
|
|
guildChannelFollowEntries,
|
|
|
|
|
guildChannelFollowJsonCount:
|
|
|
|
|
(channelFollowExportJsonRows || []).length + (guildChannelFollowEntries || []).length,
|
|
|
|
|
lastChannelFollowExport,
|
|
|
|
|
guildNotificationOverrides,
|
|
|
|
|
guildNotificationJsonCount:
|
|
|
|
@@ -33496,6 +33631,10 @@ class PearcordPlatform extends EventEmitter {
|
|
|
|
|
customStatusJsonMeta,
|
|
|
|
|
customStatusJsonRows,
|
|
|
|
|
guildWidgetExportJsonRows,
|
|
|
|
|
guildWidgetExportJsonMeta,
|
|
|
|
|
guildWidgetConfigEntries,
|
|
|
|
|
guildWidgetJsonCount:
|
|
|
|
|
(guildWidgetExportJsonRows || []).length + (guildWidgetConfigEntries || []).length,
|
|
|
|
|
lastGuildWidgetExport,
|
|
|
|
|
guildCustomStatuses,
|
|
|
|
|
activityInviteJsonMeta,
|
|
|
|
@@ -34177,6 +34316,8 @@ const { federationJsonMixin } = require('./federation-json-mixin')
|
|
|
|
|
const { meshJsonMixin } = require('./mesh-json-mixin')
|
|
|
|
|
const { multiGuildJsonMixin } = require('./multi-guild-json-mixin')
|
|
|
|
|
const { partitionHealJsonMixin } = require('./partition-heal-json-mixin')
|
|
|
|
|
const { channelFollowJsonMixin } = require('./channel-follow-json-mixin')
|
|
|
|
|
const { guildWidgetJsonMixin } = require('./guild-widget-json-mixin')
|
|
|
|
|
Object.assign(PearcordPlatform.prototype, pollSchedulingMixin)
|
|
|
|
|
Object.assign(PearcordPlatform.prototype, notificationsActivityMixin)
|
|
|
|
|
Object.assign(PearcordPlatform.prototype, userSettingsMixin)
|
|
|
|
@@ -34222,3 +34363,5 @@ Object.assign(PearcordPlatform.prototype, federationJsonMixin)
|
|
|
|
|
Object.assign(PearcordPlatform.prototype, meshJsonMixin)
|
|
|
|
|
Object.assign(PearcordPlatform.prototype, multiGuildJsonMixin)
|
|
|
|
|
Object.assign(PearcordPlatform.prototype, partitionHealJsonMixin)
|
|
|
|
|
Object.assign(PearcordPlatform.prototype, channelFollowJsonMixin)
|
|
|
|
|
Object.assign(PearcordPlatform.prototype, guildWidgetJsonMixin)
|
|
|
|
|