feat(storage): linked documents - archive linked documents

This commit is contained in:
yflory 2026-06-26 16:56:08 +02:00
parent 6c9e566695
commit e1edac8cb1
5 changed files with 68 additions and 25 deletions

View File

@ -13,6 +13,7 @@ const Channel = require("./channel");
const Invitation = require("./invitation");
const Users = require("./users");
const Moderators = require("./moderators");
const Linked = require("./linked");
const BlockStore = require("../storage/block");
const MFA = require("../storage/mfa");
const ArchiveAccount = require('../archive-account');
@ -195,16 +196,21 @@ var archiveDocument = function (Env, Server, _cb, data) {
switch (id.length) {
case 32:
return void Env.msgStore.archiveChannel(id, archiveReason, Util.both(cb, function (err) {
Env.Log.info("ARCHIVAL_CHANNEL_BY_ADMIN_RPC", {
channelId: id,
reason: reason,
status: err? String(err): "SUCCESS",
});
Channel.disconnectChannelMembers(Env, Server, id, 'EDELETED', reasonStr, err => {
if (err) { } // TODO
});
}));
return void Linked.listLinkedDocuments(Env, id, (err, channels) => {
Env.msgStore.archiveChannel(id, archiveReason, Util.both(cb, function (err) {
if (!err && channels) {
Linked.archiveLinkedData(Env, id, archiveReason, channels, () => {});
}
Env.Log.info("ARCHIVAL_CHANNEL_BY_ADMIN_RPC", {
channelId: id,
reason: reason,
status: err? String(err): "SUCCESS",
});
Channel.disconnectChannelMembers(Env, Server, id, 'EDELETED', reasonStr, err => {
if (err) { } // TODO
});
}));
});
case 48:
return void Env.blobStore.archive.blob(id, archiveReason, Util.both(cb, function (err) {
Env.Log.info("ARCHIVAL_BLOB_BY_ADMIN_RPC", {
@ -260,16 +266,22 @@ var removeDocument = function (Env, Server, cb, data) {
switch (id.length) {
case 32:
return void Env.msgStore.removeChannel(id, Util.both(cb, function (err) {
Env.Log.info("REMOVAL_CHANNEL_BY_ADMIN_RPC", {
channelId: id,
reason: reason,
status: err? String(err): "SUCCESS",
});
Channel.disconnectChannelMembers(Env, Server, id, 'EDELETED', reason, err => {
if (err) { } // TODO
});
}));
return void Linked.listLinkedDocuments(Env, id, (err, channels) => {
Env.msgStore.removeChannel(id, Util.both(cb, function (err) {
if (!err && channels) {
Linked.archiveLinkedData(Env, id, reason, channels, () => {});
}
Env.Log.info("REMOVAL_CHANNEL_BY_ADMIN_RPC", {
channelId: id,
reason: reason,
status: err? String(err): "SUCCESS",
});
if (!err) { Linked.archiveLinkedData(Env, id, reason, () => {}); }
Channel.disconnectChannelMembers(Env, Server, id, 'EDELETED', reason, err => {
if (err) { } // TODO
});
}));
});
case 48:
return void Env.blobStore.remove.blob(id, Util.both(cb, function (err) {
Env.Log.info("REMOVAL_BLOB_BY_ADMIN_RPC", {

View File

@ -172,7 +172,15 @@ Channel.removeOwnedChannel = function (Env, safeKey, obj, __cb, Server) {
if (Env.blobStore.isFileId(channelId)) {
return void Env.removeOwnedBlob(channelId, safeKey, reason, cb);
}
archiveOwnedChannel(Env, safeKey, channelId, reason, cb, Server);
Linked.listLinkedDocuments(Env, channelId, (err, channels) => {
archiveOwnedChannel(Env, safeKey, channelId, reason, (err, data) => {
if (!channels) { return void cb(err, data); }
if (err) { return void cb(err); }
Linked.archiveLinkedData(Env, channelId, reason, channels, () => {
cb(void 0, data);
});
}, Server);
});
});
};

View File

@ -413,5 +413,28 @@ Linked.trimHistory = (Env, data, cb) => {
cb();
});
});
};
// Archive all linked documents that inherit metadata from their
// parent. We consider ownership has already been checked when
// this function is called.
Linked.archiveLinkedData = (Env, channel, reason, channels, _cb) => {
const cb = Util.once(_cb);
let n = nThen;
channels.forEach(chan => {
n = n(w => {
// For each linked document, check if they inherit properties
getMetadata(Env, chan, w((err, md) => {
if (md?.linked !== channel) { return; }
// If they do, archive the document
if (chan.length === HK.BLOB_ID_LENGTH) {
return Env.blobStore.archive.blob(chan, reason, w());
}
Env.store.archiveChannel(chan, reason, w());
}));
}).nThen;
});
n(() => {
cb();
});
};

View File

@ -40,7 +40,8 @@ Data.getMetadataRaw = function (Env, channel, _cb, resolveLinked) {
Env.checkCache(channel);
}
if (resolveLinked && meta?.linked?.length === HK.STANDARD_CHANNEL_LENGTH) {
if (resolveLinked && meta?.linked?.length === HK.STANDARD_CHANNEL_LENGTH
&& meta?.linked !== channel) {
Data.getMetadataRaw(Env, meta.linked, (err, _meta) => {
meta.owners = _meta.owners;
meta.restricted = _meta.restricted;

View File

@ -1757,8 +1757,7 @@ define([
var optsPut = {
password: newPassword,
metadata: {
validateKey: newSecret.keys.validateKey,
linked: newSecret.channel
validateKey: newSecret.keys.validateKey
},
};
var optsGet = {