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) {
|
||||
if (this.summary) {
|
||||
return this.summary.trim();
|
||||
|
|
|
@ -100,6 +100,7 @@ module.exports = () => {
|
|||
'server',
|
||||
'client',
|
||||
'notme',
|
||||
'public',
|
||||
],
|
||||
|
||||
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) {
|
||||
if (!_.isFunction(cb) && _.isFunction(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) {
|
||||
if (!this.isValid()) {
|
||||
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) {
|
||||
if (!this.userHasDeleteRights(requestingUser)) {
|
||||
return cb(
|
||||
|
|
|
@ -532,8 +532,28 @@ exports.getModule = class ActivityPubWebHandler extends WebHandlerModule {
|
|||
objInfo.object,
|
||||
stats,
|
||||
() => {
|
||||
if ('Note' === objInfo.object.type) {
|
||||
// :TODO: delete associated message!
|
||||
// if it was a Note before...
|
||||
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);
|
||||
|
@ -578,6 +598,58 @@ exports.getModule = class ActivityPubWebHandler extends WebHandlerModule {
|
|||
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) {
|
||||
const objectId = _.isString(object) ? object : object.id;
|
||||
const type = object.type;
|
||||
|
@ -806,7 +878,8 @@ exports.getModule = class ActivityPubWebHandler extends WebHandlerModule {
|
|||
`${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);
|
||||
}
|
||||
|
|
Loading…
Reference in New Issue