mirror of
https://github.com/paricafe/misskey.git
synced 2024-11-24 15:16:44 -06:00
chore: tweak note update handler
to prevent possible version corruption caused by deliver delay
This commit is contained in:
parent
678aa493de
commit
7dc31a3ac1
3 changed files with 49 additions and 17 deletions
|
@ -68,6 +68,15 @@ export class NoteUpdateService {
|
|||
* @param ps New note info
|
||||
*/
|
||||
async update(user: { id: MiUser['id']; uri: MiUser['uri']; host: MiUser['host']; isBot: MiUser['isBot']; }, note: MiNote, ps: Pick<MiNote, 'text' | 'cw' | 'updatedAt'>, quiet = false, updater?: MiUser) {
|
||||
if (!ps.updatedAt) {
|
||||
throw new Error('update time is required');
|
||||
}
|
||||
|
||||
if (note.history?.findIndex(h => h.createdAt === ps.updatedAt?.toISOString()) !== -1) {
|
||||
// Same history already exists, skip this
|
||||
return;
|
||||
}
|
||||
|
||||
const newNote = {
|
||||
...note,
|
||||
...ps, // Overwrite updated fields
|
||||
|
@ -90,18 +99,33 @@ export class NoteUpdateService {
|
|||
}
|
||||
}
|
||||
|
||||
this.searchService.indexNote(newNote);
|
||||
|
||||
await this.notesRepository.update({ id: note.id }, {
|
||||
updatedAt: ps.updatedAt,
|
||||
history: [...(note.history || []), {
|
||||
// Check if is latest or previous version
|
||||
const history = [...(note.history || []), {
|
||||
createdAt: (note.updatedAt || this.idService.parse(note.id).date).toISOString(),
|
||||
cw: note.cw,
|
||||
text: note.text,
|
||||
}],
|
||||
}];
|
||||
if (note.updatedAt && note.updatedAt >= ps.updatedAt) {
|
||||
// Previous version, just update history
|
||||
history.sort((h1, h2) => new Date(h1.createdAt).getTime() - new Date(h2.createdAt).getTime()); // earliest -> latest
|
||||
|
||||
await this.notesRepository.update({ id: note.id }, {
|
||||
history,
|
||||
});
|
||||
} else {
|
||||
// Latest version
|
||||
|
||||
// Update index
|
||||
this.searchService.indexNote(newNote);
|
||||
|
||||
// Update note info
|
||||
await this.notesRepository.update({ id: note.id }, {
|
||||
updatedAt: ps.updatedAt,
|
||||
history,
|
||||
cw: ps.cw,
|
||||
text: ps.text,
|
||||
});
|
||||
}
|
||||
|
||||
// Currently not implemented
|
||||
// if (updater && (note.userId !== updater.id)) {
|
||||
|
|
|
@ -335,17 +335,22 @@ export class ApNoteService {
|
|||
const uri = typeof value === 'string' ? value : value.id;
|
||||
if (uri == null) throw new Error('uri is null');
|
||||
|
||||
// Is from local
|
||||
// Check if note is from local
|
||||
if (uri.startsWith(`${this.config.url}/`)) throw new Error('uri points local');
|
||||
|
||||
const originNote = await this.notesRepository.findOneBy({ uri });
|
||||
if (originNote == null) throw new Error('Note is not registered');
|
||||
if (originNote === null) throw new Error('note is not registered');
|
||||
|
||||
// Process new note
|
||||
const note = value as IPost;
|
||||
|
||||
// Check updated timestamp
|
||||
if (!note.updated) {
|
||||
throw new Error('note.updated field is required');
|
||||
}
|
||||
|
||||
// Fetch note author
|
||||
if (note.attributedTo == null) {
|
||||
if (!note.attributedTo) {
|
||||
throw new Error('invalid note.attributedTo: ' + note.attributedTo);
|
||||
}
|
||||
|
||||
|
@ -363,12 +368,10 @@ export class ApNoteService {
|
|||
text = this.apMfmService.htmlToMfm(note.content, note.tag);
|
||||
}
|
||||
|
||||
const updatedAt = note.updated || new Date();
|
||||
|
||||
await this.noteUpdateService.update(actor, originNote, {
|
||||
cw,
|
||||
text,
|
||||
updatedAt,
|
||||
updatedAt: note.updated,
|
||||
}, silent);
|
||||
}
|
||||
|
||||
|
|
|
@ -70,6 +70,11 @@ export default class extends Endpoint<typeof meta, typeof paramDef> { // eslint-
|
|||
throw new ApiError(meta.errors.noSuchNote);
|
||||
}
|
||||
|
||||
if (note.text === ps.text && note.cw === ps.cw) {
|
||||
// The same as old note, nothing to do
|
||||
return;
|
||||
}
|
||||
|
||||
await this.noteUpdateService.update(await this.usersRepository.findOneByOrFail({ id: note.userId }), note, {
|
||||
text: ps.text,
|
||||
cw: ps.cw,
|
||||
|
|
Loading…
Reference in a new issue