Handling Update/Delete better
This commit is contained in:
parent
3212d809df
commit
8b6d564ebf
|
@ -313,6 +313,89 @@ module.exports = class Note extends ActivityPubObject {
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
|
toUpdatedMessage(options, cb) {
|
||||||
|
const original = new Message();
|
||||||
|
original.load({ uuid: options.messageUuid }, err => {
|
||||||
|
if (err) {
|
||||||
|
return cb(err);
|
||||||
|
}
|
||||||
|
|
||||||
|
// rebuild message
|
||||||
|
options.areaTag = original.areaTag;
|
||||||
|
|
||||||
|
async.waterfall(
|
||||||
|
[
|
||||||
|
callback => {
|
||||||
|
if (!original.isPrivate()) {
|
||||||
|
options.toUser = 'All';
|
||||||
|
return callback(null);
|
||||||
|
}
|
||||||
|
|
||||||
|
const userId =
|
||||||
|
original.meta.System[Message.SystemMetaNames.LocalToUserID];
|
||||||
|
if (!userId) {
|
||||||
|
return cb(
|
||||||
|
Errors.MissingProperty(
|
||||||
|
`User is missing "${Message.SystemMetaNames.LocalToUserID}" property`
|
||||||
|
)
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
User.getUser(userId, (err, user) => {
|
||||||
|
if (err) {
|
||||||
|
return callback(err);
|
||||||
|
}
|
||||||
|
|
||||||
|
options.toUser = user;
|
||||||
|
return callback(null);
|
||||||
|
});
|
||||||
|
},
|
||||||
|
callback => {
|
||||||
|
this.toMessage(options, (err, message) => {
|
||||||
|
if (err) {
|
||||||
|
return callback(err);
|
||||||
|
}
|
||||||
|
|
||||||
|
// re-target as message to be updated
|
||||||
|
message.messageUuid = original.messageUuid;
|
||||||
|
|
||||||
|
return callback(null, message);
|
||||||
|
});
|
||||||
|
},
|
||||||
|
],
|
||||||
|
(err, message) => {
|
||||||
|
return cb(err, message);
|
||||||
|
}
|
||||||
|
);
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
static deleteAssocMessage(noteId, cb) {
|
||||||
|
const filter = {
|
||||||
|
resultType: 'uuid',
|
||||||
|
metaTuples: [
|
||||||
|
{
|
||||||
|
category: Message.WellKnownMetaCategories.ActivityPub,
|
||||||
|
name: Message.ActivityPubPropertyNames.NoteId,
|
||||||
|
value: noteId,
|
||||||
|
},
|
||||||
|
],
|
||||||
|
limit: 1,
|
||||||
|
};
|
||||||
|
|
||||||
|
return Message.findMessages(filter, (err, messageUuid) => {
|
||||||
|
if (!messageUuid) {
|
||||||
|
return cb(null);
|
||||||
|
}
|
||||||
|
|
||||||
|
messageUuid = messageUuid[0]; // limit 1
|
||||||
|
|
||||||
|
Message.deleteByMessageUuid(messageUuid, err => {
|
||||||
|
return cb(err);
|
||||||
|
});
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
_getSubject(message) {
|
_getSubject(message) {
|
||||||
if (this.summary) {
|
if (this.summary) {
|
||||||
return this.summary.trim();
|
return this.summary.trim();
|
||||||
|
|
|
@ -100,6 +100,7 @@ module.exports = () => {
|
||||||
'server',
|
'server',
|
||||||
'client',
|
'client',
|
||||||
'notme',
|
'notme',
|
||||||
|
'public',
|
||||||
],
|
],
|
||||||
|
|
||||||
preAuthIdleLogoutSeconds: 60 * 3, // 3m
|
preAuthIdleLogoutSeconds: 60 * 3, // 3m
|
||||||
|
|
123
core/message.js
123
core/message.js
|
@ -708,6 +708,17 @@ module.exports = class Message {
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static deleteByMessageUuid(messageUuid, cb) {
|
||||||
|
msgDb.run(
|
||||||
|
`DELETE FROM message
|
||||||
|
WHERE message_uuid = ?;`,
|
||||||
|
[messageUuid],
|
||||||
|
err => {
|
||||||
|
return cb(err);
|
||||||
|
}
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
persistMetaValue(category, name, value, transOrDb, cb) {
|
persistMetaValue(category, name, value, transOrDb, cb) {
|
||||||
if (!_.isFunction(cb) && _.isFunction(transOrDb)) {
|
if (!_.isFunction(cb) && _.isFunction(transOrDb)) {
|
||||||
cb = transOrDb;
|
cb = transOrDb;
|
||||||
|
@ -738,6 +749,34 @@ module.exports = class Message {
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
updateMetaValue(category, name, value, transOrDb, cb) {
|
||||||
|
if (!_.isFunction(cb) && _.isFunction(transOrDb)) {
|
||||||
|
cb = transOrDb;
|
||||||
|
transOrDb = msgDb;
|
||||||
|
}
|
||||||
|
|
||||||
|
const metaStmt = transOrDb.prepare(
|
||||||
|
`REPLACE INTO message_meta (message_id, meta_category, meta_name, meta_value)
|
||||||
|
VALUES (?, ?, ?, ?);`
|
||||||
|
);
|
||||||
|
|
||||||
|
if (!_.isArray(value)) {
|
||||||
|
value = [value];
|
||||||
|
}
|
||||||
|
|
||||||
|
async.each(
|
||||||
|
value,
|
||||||
|
(v, next) => {
|
||||||
|
metaStmt.run(this.messageId, category, name, v, err => {
|
||||||
|
return next(err);
|
||||||
|
});
|
||||||
|
},
|
||||||
|
err => {
|
||||||
|
return cb(err);
|
||||||
|
}
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
persist(cb) {
|
persist(cb) {
|
||||||
if (!this.isValid()) {
|
if (!this.isValid()) {
|
||||||
return cb(Errors.Invalid('Cannot persist invalid message!'));
|
return cb(Errors.Invalid('Cannot persist invalid message!'));
|
||||||
|
@ -843,6 +882,90 @@ module.exports = class Message {
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
update(cb) {
|
||||||
|
if (!this.isValid()) {
|
||||||
|
return cb(Errors.Invalid('Cannot update invalid message!'));
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!this.messageUuid) {
|
||||||
|
return cb(Errors.Invalid("Cannot update without a valid 'messageUUID'"));
|
||||||
|
}
|
||||||
|
|
||||||
|
const self = this;
|
||||||
|
|
||||||
|
async.waterfall(
|
||||||
|
[
|
||||||
|
callback => {
|
||||||
|
return msgDb.beginTransaction(callback);
|
||||||
|
},
|
||||||
|
(trans, callback) => {
|
||||||
|
trans.run(
|
||||||
|
`REPLACE INTO message (area_tag, message_uuid, reply_to_message_id, to_user_name, from_user_name, subject, message, modified_timestamp)
|
||||||
|
VALUES (?, ?, ?, ?, ?, ?, ?, ?);`,
|
||||||
|
[
|
||||||
|
this.areaTag,
|
||||||
|
this.messageUuid,
|
||||||
|
this.replyToMsgId,
|
||||||
|
this.toUserName,
|
||||||
|
this.fromUserName,
|
||||||
|
this.subject,
|
||||||
|
this.message,
|
||||||
|
getISOTimestampString(this.modTimestamp),
|
||||||
|
],
|
||||||
|
function inserted(err) {
|
||||||
|
// use non-arrow function for 'this' scope
|
||||||
|
if (!err) {
|
||||||
|
self.messageId = this.lastID;
|
||||||
|
}
|
||||||
|
|
||||||
|
return callback(err, trans);
|
||||||
|
}
|
||||||
|
);
|
||||||
|
},
|
||||||
|
(trans, callback) => {
|
||||||
|
if (!this.meta) {
|
||||||
|
return callback(null, trans);
|
||||||
|
}
|
||||||
|
|
||||||
|
async.each(
|
||||||
|
Object.keys(this.meta),
|
||||||
|
(category, nextCat) => {
|
||||||
|
async.each(
|
||||||
|
Object.keys(this.meta[category]),
|
||||||
|
(name, nextName) => {
|
||||||
|
this.updateMetaValue(
|
||||||
|
category,
|
||||||
|
name,
|
||||||
|
this.meta[category][name],
|
||||||
|
trans,
|
||||||
|
err => {
|
||||||
|
return nextName(err);
|
||||||
|
}
|
||||||
|
);
|
||||||
|
},
|
||||||
|
err => {
|
||||||
|
return nextCat(err);
|
||||||
|
}
|
||||||
|
);
|
||||||
|
},
|
||||||
|
err => {
|
||||||
|
return callback(err, trans);
|
||||||
|
}
|
||||||
|
);
|
||||||
|
},
|
||||||
|
],
|
||||||
|
(err, trans) => {
|
||||||
|
if (trans) {
|
||||||
|
trans[err ? 'rollback' : 'commit'](transErr => {
|
||||||
|
return cb(err ? err : transErr, self.messageId);
|
||||||
|
});
|
||||||
|
} else {
|
||||||
|
return cb(err);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
deleteMessage(requestingUser, cb) {
|
deleteMessage(requestingUser, cb) {
|
||||||
if (!this.userHasDeleteRights(requestingUser)) {
|
if (!this.userHasDeleteRights(requestingUser)) {
|
||||||
return cb(
|
return cb(
|
||||||
|
|
|
@ -532,8 +532,28 @@ exports.getModule = class ActivityPubWebHandler extends WebHandlerModule {
|
||||||
objInfo.object,
|
objInfo.object,
|
||||||
stats,
|
stats,
|
||||||
() => {
|
() => {
|
||||||
if ('Note' === objInfo.object.type) {
|
// if it was a Note before...
|
||||||
// :TODO: delete associated message!
|
if (
|
||||||
|
Collections.Inbox ===
|
||||||
|
objInfo.info.name ||
|
||||||
|
Collections.SharedInbox ===
|
||||||
|
objInfo.info.name
|
||||||
|
) {
|
||||||
|
return Note.deleteAssocMessage(
|
||||||
|
objectId,
|
||||||
|
err => {
|
||||||
|
if (err) {
|
||||||
|
this.log.warn(
|
||||||
|
{
|
||||||
|
error: err.message,
|
||||||
|
noteId: objectId,
|
||||||
|
},
|
||||||
|
'Failed to remove message associated with Note'
|
||||||
|
);
|
||||||
|
}
|
||||||
|
return nextObjInfo(null);
|
||||||
|
}
|
||||||
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
return nextObjInfo(null);
|
return nextObjInfo(null);
|
||||||
|
@ -578,6 +598,58 @@ exports.getModule = class ActivityPubWebHandler extends WebHandlerModule {
|
||||||
return this.webServer.accepted(resp);
|
return this.webServer.accepted(resp);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
_updateMessageAssocWithNote(objectId, activity) {
|
||||||
|
const filter = {
|
||||||
|
resultType: 'uuid',
|
||||||
|
metaTuples: [
|
||||||
|
{
|
||||||
|
category: Message.WellKnownMetaCategories.ActivityPub,
|
||||||
|
name: Message.ActivityPubPropertyNames.NoteId,
|
||||||
|
value: objectId,
|
||||||
|
},
|
||||||
|
],
|
||||||
|
limit: 1,
|
||||||
|
};
|
||||||
|
|
||||||
|
Message.findMessages(filter, (err, messageUuid) => {
|
||||||
|
if (!messageUuid) {
|
||||||
|
return this.log.warn(
|
||||||
|
{ messageUuid },
|
||||||
|
'Failed to find message for Update Note'
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
messageUuid = messageUuid[0]; // limit 1
|
||||||
|
|
||||||
|
const note = new Note(activity.object);
|
||||||
|
if (!note.isValid()) {
|
||||||
|
return this.log.error('Note within Update does not appear to be valid');
|
||||||
|
}
|
||||||
|
|
||||||
|
const updateOpts = {
|
||||||
|
messageUuid,
|
||||||
|
};
|
||||||
|
|
||||||
|
note.toUpdatedMessage(updateOpts, (err, message) => {
|
||||||
|
if (err) {
|
||||||
|
return this.log.error(
|
||||||
|
{ error: err.message, messageUuid, step: 'Note to Message' },
|
||||||
|
'Note Update failed to update underlying message'
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
message.update(err => {
|
||||||
|
if (err) {
|
||||||
|
this.log.error(
|
||||||
|
{ error: err.message, messageUuid, step: 'Persist' },
|
||||||
|
'Note Update failed to update underlying message'
|
||||||
|
);
|
||||||
|
}
|
||||||
|
});
|
||||||
|
});
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
_deleteObjectWithStats(collectionName, object, stats, cb) {
|
_deleteObjectWithStats(collectionName, object, stats, cb) {
|
||||||
const objectId = _.isString(object) ? object : object.id;
|
const objectId = _.isString(object) ? object : object.id;
|
||||||
const type = object.type;
|
const type = object.type;
|
||||||
|
@ -806,7 +878,8 @@ exports.getModule = class ActivityPubWebHandler extends WebHandlerModule {
|
||||||
`${objectType} Updated`
|
`${objectType} Updated`
|
||||||
);
|
);
|
||||||
|
|
||||||
// :TODO: we need to UPDATE the existing stored Message object if this is a Note
|
// Update any assoc Message object
|
||||||
|
this._updateMessageAssocWithNote(targetObjectId, activity);
|
||||||
|
|
||||||
return this.webServer.accepted(resp);
|
return this.webServer.accepted(resp);
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in New Issue